diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/Attackable.java index a11a4feb0c..e1eaf10033 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -67,6 +66,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1097,12 +1097,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_2.5_Underground/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_2.5_Underground/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 92476d9a03..303090c8e4 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -66,6 +65,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1093,12 +1093,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_3.0_Helios/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_3.0_Helios/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 92476d9a03..303090c8e4 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -66,6 +65,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1093,12 +1093,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 92476d9a03..303090c8e4 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -66,6 +65,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1093,12 +1093,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_5.0_Salvation/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_5.0_Salvation/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 1a92f29a43..2a31621a1e 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -65,6 +64,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1082,12 +1082,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_5.5_EtinasFate/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 1a92f29a43..2a31621a1e 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -65,6 +64,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1082,12 +1082,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_6.0_Fafurion/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_6.0_Fafurion/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 1a92f29a43..2a31621a1e 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -65,6 +64,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1082,12 +1082,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 1a88f164a0..4473469492 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -65,6 +64,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1090,12 +1090,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_CT_2.4_Epilogue/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_CT_2.4_Epilogue/dist/game/data/xsd/eventConfig.xsd index 10a65330d5..efc8ade696 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_CT_2.4_Epilogue/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 4b67307866..aa5d4f98e8 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/Attackable.java index c2ce6f3575..96aba82eea 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -35,7 +35,6 @@ import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.FortSiegeGuardAI; import org.l2jmobius.gameserver.ai.SiegeGuardAI; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -61,6 +60,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.attackable.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.attackable.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.attackable.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1044,18 +1044,28 @@ public class Attackable extends Npc final PlayerInstance player = lastAttacker.getActingPlayer(); // Don't drop anything if the last attacker or owner isn't PlayerInstance - if ((player == null) || ((player.getLevel() - getLevel()) > 9)) + if (player == null) + { + return; + } + + if ((player.getLevel() - getLevel()) > 9) { return; } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index a88a142c68..59d68e6a13 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -43,7 +43,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -57,8 +57,9 @@ public class LongTimeEvent extends Quest private String _eventName; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -67,7 +68,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -169,7 +170,20 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - final int finalChance = !chance.isEmpty() && chance.endsWith("%") ? Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000 : 0; + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) + { + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } + } if (ItemTable.getInstance().getTemplate(itemId) == null) { @@ -183,13 +197,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -293,18 +307,17 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - final long currentTime = System.currentTimeMillis(); - // Add drop - if ((_dropList != null) && (currentTime < _dropPeriod.getEndDate().getTime())) + // Add drop. + if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns - final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - currentTime; + // Add spawns. + final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { for (NpcSpawn spawn : _spawnList) @@ -313,13 +326,19 @@ public class LongTimeEvent extends Quest } } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -363,8 +382,18 @@ public class LongTimeEvent extends Quest { // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -382,7 +411,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index 04b48ab76f..0000000000 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/eventConfig.xsd index 10a65330d5..efc8ade696 100644 --- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 4b67307866..aa5d4f98e8 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/Attackable.java index c2ce6f3575..96aba82eea 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -35,7 +35,6 @@ import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.FortSiegeGuardAI; import org.l2jmobius.gameserver.ai.SiegeGuardAI; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -61,6 +60,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.attackable.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.attackable.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.attackable.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1044,18 +1044,28 @@ public class Attackable extends Npc final PlayerInstance player = lastAttacker.getActingPlayer(); // Don't drop anything if the last attacker or owner isn't PlayerInstance - if ((player == null) || ((player.getLevel() - getLevel()) > 9)) + if (player == null) + { + return; + } + + if ((player.getLevel() - getLevel()) > 9) { return; } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index a88a142c68..59d68e6a13 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -43,7 +43,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -57,8 +57,9 @@ public class LongTimeEvent extends Quest private String _eventName; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -67,7 +68,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -169,7 +170,20 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - final int finalChance = !chance.isEmpty() && chance.endsWith("%") ? Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000 : 0; + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) + { + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } + } if (ItemTable.getInstance().getTemplate(itemId) == null) { @@ -183,13 +197,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -293,18 +307,17 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - final long currentTime = System.currentTimeMillis(); - // Add drop - if ((_dropList != null) && (currentTime < _dropPeriod.getEndDate().getTime())) + // Add drop. + if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns - final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - currentTime; + // Add spawns. + final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { for (NpcSpawn spawn : _spawnList) @@ -313,13 +326,19 @@ public class LongTimeEvent extends Quest } } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -363,8 +382,18 @@ public class LongTimeEvent extends Quest { // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -382,7 +411,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index 04b48ab76f..0000000000 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/Attackable.java index a317332bba..89a18463a4 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -66,6 +65,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1093,12 +1093,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/Attackable.java index a317332bba..89a18463a4 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -66,6 +65,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1093,12 +1093,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/Attackable.java index a317332bba..89a18463a4 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -66,6 +65,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1093,12 +1093,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 4dc03ef862..ee21e2f012 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -68,6 +67,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1115,12 +1115,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 4dc03ef862..ee21e2f012 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -68,6 +67,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1115,12 +1115,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 4dc03ef862..ee21e2f012 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -68,6 +67,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1115,12 +1115,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -} diff --git a/L2J_Mobius_Classic_Interlude/dist/game/data/xsd/eventConfig.xsd b/L2J_Mobius_Classic_Interlude/dist/game/data/xsd/eventConfig.xsd index c9b013b446..019149a5af 100644 --- a/L2J_Mobius_Classic_Interlude/dist/game/data/xsd/eventConfig.xsd +++ b/L2J_Mobius_Classic_Interlude/dist/game/data/xsd/eventConfig.xsd @@ -12,6 +12,9 @@ + + + diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/datatables/EventDroplist.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/datatables/EventDroplist.java index 2fce996a09..1dcf376950 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/datatables/EventDroplist.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/datatables/EventDroplist.java @@ -16,14 +16,13 @@ */ package org.l2jmobius.gameserver.datatables; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; -import org.l2jmobius.gameserver.script.EventDrop; /** * This class manage drop of Special Events created by GM for a defined period.
@@ -38,28 +37,22 @@ public class EventDroplist */ private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - public static class DateDrop + private static final class DateDrop { - protected final DateRange _dateRange; - private final EventDrop _eventDrop; + private final DateRange _dateRange; + private final EventDropHolder _eventDrop; - public DateDrop(DateRange dateRange, EventDrop eventDrop) + public DateDrop(DateRange dateRange, EventDropHolder eventDrop) { _dateRange = dateRange; _eventDrop = eventDrop; } - /** - * @return the _eventDrop - */ - public EventDrop getEventDrop() + public EventDropHolder getEventDrop() { return _eventDrop; } - /** - * @return the _dateRange - */ public DateRange getDateRange() { return _dateRange; @@ -67,51 +60,26 @@ public class EventDroplist } /** - * Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist . - * @param itemIdList The table containing all item identifier of this DateDrop - * @param count The table containing min and max value of this DateDrop - * @param chance The chance to obtain this drop - * @param dateRange The DateRange object to add to this DateDrop - */ - public void addGlobalDrop(int[] itemIdList, int[] count, int chance, DateRange dateRange) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemIdList, count[0], count[1], chance))); - } - - /** - * @param itemId the item Id for the drop - * @param min the minimum drop count - * @param max the maximum drop count - * @param chance the drop chance * @param dateRange the event drop rate range + * @param drop the event drop */ - public void addGlobalDrop(int itemId, long min, long max, int chance, DateRange dateRange) + public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, new EventDrop(itemId, min, max, chance))); - } - - /** - * Adds an event drop for a given date range. - * @param dateRange the date range. - * @param eventDrop the event drop. - */ - public void addGlobalDrop(DateRange dateRange, EventDrop eventDrop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, eventDrop)); + ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); } /** * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. */ - public List getAllDrops() + public Collection getAllDrops() { - final List list = new LinkedList<>(); + final Collection list = new ArrayList<>(); final Date currentDate = new Date(); for (DateDrop drop : ALL_NPC_DATE_DROPS) { - if (drop._dateRange.isWithinRange(currentDate)) + if (drop.getDateRange().isWithinRange(currentDate)) { - list.add(drop); + list.add(drop.getEventDrop()); } } return list; diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/Attackable.java index a317332bba..89a18463a4 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -38,7 +38,6 @@ import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.data.xml.impl.ExtendDropData; import org.l2jmobius.gameserver.datatables.EventDroplist; -import org.l2jmobius.gameserver.datatables.EventDroplist.DateDrop; import org.l2jmobius.gameserver.datatables.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -66,6 +65,7 @@ import org.l2jmobius.gameserver.model.events.EventDispatcher; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAggroRangeEnter; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack; import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableKill; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.model.holders.ItemHolder; import org.l2jmobius.gameserver.model.holders.SkillHolder; import org.l2jmobius.gameserver.model.items.Item; @@ -1093,12 +1093,17 @@ public class Attackable extends Npc } // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (DateDrop drop : EventDroplist.getInstance().getAllDrops()) + for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) { - if (Rnd.get(1000000) < drop.getEventDrop().getDropChance()) + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) { - final int itemId = drop.getEventDrop().getItemIdList()[Rnd.get(drop.getEventDrop().getItemIdList().length)]; - final long itemCount = Rnd.get(drop.getEventDrop().getMinCount(), drop.getEventDrop().getMaxCount()); + continue; + } + final int monsterLevel = getLevel(); + if ((monsterLevel >= drop.getMinLevel()) && (monsterLevel <= drop.getMaxLevel()) && (Rnd.get(100d) < drop.getChance())) + { + final int itemId = drop.getItemId(); + final long itemCount = Rnd.get(drop.getMin(), drop.getMax()); if (Config.AUTO_LOOT_ITEM_IDS.contains(itemId) || Config.AUTO_LOOT || isFlying()) { player.doAutoLoot(this, itemId, itemCount); // Give the item(s) to the PlayerInstance that has killed the Attackable diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java new file mode 100644 index 0000000000..f26329bc21 --- /dev/null +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/holders/EventDropHolder.java @@ -0,0 +1,52 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 . + */ +package org.l2jmobius.gameserver.model.holders; + +import java.util.Collection; + +/** + * @author Mobius + */ +public class EventDropHolder extends DropHolder +{ + private final int _minLevel; + private final int _maxLevel; + private final Collection _monsterIds; + + public EventDropHolder(int itemId, long min, long max, double chance, int minLevel, int maxLevel, Collection monsterIds) + { + super(null, itemId, min, max, chance); + _minLevel = minLevel; + _maxLevel = maxLevel; + _monsterIds = monsterIds; + } + + public int getMinLevel() + { + return _minLevel; + } + + public int getMaxLevel() + { + return _maxLevel; + } + + public Collection getMonsterIds() + { + return _monsterIds; + } +} diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index ba6ae0fb56..34537f5252 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -42,7 +42,7 @@ import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.announce.EventAnnouncement; -import org.l2jmobius.gameserver.model.holders.DropHolder; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; import org.l2jmobius.gameserver.script.DateRange; import org.l2jmobius.gameserver.util.Broadcast; @@ -58,8 +58,9 @@ public class LongTimeEvent extends Quest boolean _enableShrines = false; // Messages - protected String _onEnterMsg = "Event is in process"; - protected String _endMsg = "Event ends!"; + protected String _onEnterMsg = ""; + protected String _endMsg = ""; + private int _enterAnnounceId = -1; protected DateRange _eventPeriod = null; protected DateRange _dropPeriod; @@ -68,7 +69,7 @@ public class LongTimeEvent extends Quest protected final List _spawnList = new ArrayList<>(); // Drop data for event - protected final List _dropList = new ArrayList<>(); + protected final List _dropList = new ArrayList<>(); // Items to destroy when event ends. protected final List _destoyItemsOnEnd = new ArrayList<>(); @@ -165,8 +166,7 @@ public class LongTimeEvent extends Quest if (_eventPeriod.getStartDate().after(today) || _eventPeriod.isWithinRange(today)) { - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { // Loading droplist if (n.getNodeName().equalsIgnoreCase("droplist")) @@ -181,11 +181,19 @@ public class LongTimeEvent extends Quest final int minCount = Integer.parseInt(d.getAttributes().getNamedItem("min").getNodeValue()); final int maxCount = Integer.parseInt(d.getAttributes().getNamedItem("max").getNodeValue()); final String chance = d.getAttributes().getNamedItem("chance").getNodeValue(); - int finalChance = 0; - - if (!chance.isEmpty() && chance.endsWith("%")) + final double finalChance = !chance.isEmpty() && chance.endsWith("%") ? Double.parseDouble(chance.substring(0, chance.length() - 1)) : 0; + final Node minLevelNode = d.getAttributes().getNamedItem("minLevel"); + final int minLevel = minLevelNode == null ? 1 : Integer.parseInt(minLevelNode.getNodeValue()); + final Node maxLevelNode = d.getAttributes().getNamedItem("maxLevel"); + final int maxLevel = maxLevelNode == null ? Integer.MAX_VALUE : Integer.parseInt(maxLevelNode.getNodeValue()); + final Node monsterIdsNode = d.getAttributes().getNamedItem("monsterIds"); + final List monsterIds = new ArrayList<>(); + if (monsterIdsNode != null) { - finalChance = Integer.parseInt(chance.substring(0, chance.length() - 1)) * 10000; + for (String id : monsterIdsNode.getNodeValue().split(",")) + { + monsterIds.add(Integer.parseInt(id)); + } } if (ItemTable.getInstance().getTemplate(itemId) == null) @@ -200,13 +208,13 @@ public class LongTimeEvent extends Quest continue; } - if ((finalChance < 10000) || (finalChance > 1000000)) + if ((finalChance < 0) || (finalChance > 100)) { LOGGER.warning(getScriptName() + " event: item " + itemId + " - incorrect drop chance, item was not added in droplist"); continue; } - _dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance)); + _dropList.add(new EventDropHolder(itemId, minCount, maxCount, finalChance, minLevel, maxLevel, monsterIds)); } catch (NumberFormatException nfe) { @@ -272,8 +280,7 @@ public class LongTimeEvent extends Quest } // Load destroy item list at all times. - final Node first = doc.getDocumentElement().getFirstChild(); - for (Node n = first; n != null; n = n.getNextSibling()) + for (Node n = doc.getDocumentElement().getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeName().equalsIgnoreCase("destoyItemsOnEnd")) { @@ -309,16 +316,16 @@ public class LongTimeEvent extends Quest */ protected void startEvent() { - // Add drop + // Add drop. if (_dropList != null) { - for (DropHolder drop : _dropList) + for (EventDropHolder drop : _dropList) { - EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod); + EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); } } - // Add spawns + // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - System.currentTimeMillis(); if (_spawnList != null) { @@ -328,19 +335,25 @@ public class LongTimeEvent extends Quest } } - // Enable town shrines + // Enable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(true); } - // Send message on begin - Broadcast.toAllOnlinePlayers(_onEnterMsg); + // Event enter announcement. + if (!_onEnterMsg.isEmpty()) + { + // Send message on begin. + Broadcast.toAllOnlinePlayers(_onEnterMsg); + + // Add announce for entering players. + final EventAnnouncement announce = new EventAnnouncement(_eventPeriod, _onEnterMsg); + AnnouncementsTable.getInstance().addAnnouncement(announce); + _enterAnnounceId = announce.getId(); + } - // Add announce for entering players - AnnouncementsTable.getInstance().addAnnouncement(new EventAnnouncement(_eventPeriod, _onEnterMsg)); - - // Schedule event end (now only for message sending) + // Schedule event end. ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } @@ -382,15 +395,26 @@ public class LongTimeEvent extends Quest @Override public void run() { - // Disable town shrines + // Disable town shrines. if (_enableShrines) { EventShrineManager.getInstance().setEnabled(false); } + // Destroy items that must exist only on event period. destoyItemsOnEnd(); - // Send message on end - Broadcast.toAllOnlinePlayers(_endMsg); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } } } @@ -408,7 +432,7 @@ public class LongTimeEvent extends Quest player.destroyItemByItemId(_eventName, itemId, -1, player, true); } } - // Update database + // Update database. try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("DELETE FROM items WHERE item_id=?")) { diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/script/EventDrop.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/script/EventDrop.java deleted file mode 100644 index e3d9a84d8b..0000000000 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/script/EventDrop.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * 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 . - */ -package org.l2jmobius.gameserver.script; - -/** - * @author Zoey76 - */ -public class EventDrop -{ - private final int[] _itemIdList; - private final long _minCount; - private final long _maxCount; - private final int _dropChance; - - public EventDrop(int[] itemIdList, long min, long max, int dropChance) - { - _itemIdList = itemIdList; - _minCount = min; - _maxCount = max; - _dropChance = dropChance; - } - - public EventDrop(int itemId, long minCount, long maxCount, int dropChance) - { - _itemIdList = new int[] - { - itemId - }; - _minCount = minCount; - _maxCount = maxCount; - _dropChance = dropChance; - } - - /** - * @return the _itemId - */ - public int[] getItemIdList() - { - return _itemIdList; - } - - /** - * @return the _minCount - */ - public long getMinCount() - { - return _minCount; - } - - /** - * @return the _maxCount - */ - public long getMaxCount() - { - return _maxCount; - } - - /** - * @return the _dropChance - */ - public int getDropChance() - { - return _dropChance; - } -}