From 2dcb626712aee6714569eee6b6ff5af875faee3e Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Thu, 22 Jul 2021 11:03:19 +0000 Subject: [PATCH] Addition of EventDropManager class. --- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 103 ++---------- .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 66 +------- .../gameserver/model/quest/LongTimeEvent.java | 144 ++++++---------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 66 +------- .../gameserver/model/quest/LongTimeEvent.java | 144 ++++++---------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- .../org/l2jmobius/gameserver/GameServer.java | 4 +- .../gameserver/data/EventDroplist.java | 97 ----------- .../instancemanager/EventDropManager.java | 102 +++++++++++ .../gameserver/model/actor/Attackable.java | 65 +------ .../gameserver/model/quest/LongTimeEvent.java | 158 +++++++----------- 115 files changed, 3842 insertions(+), 5968 deletions(-) delete mode 100644 L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java delete mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/data/EventDroplist.java create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/GameServer.java index 64c9c57f7d..4acde36f51 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -115,6 +114,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -325,7 +325,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 b2ca418a81..6a0f8387ce 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AbsorberInfo; @@ -64,7 +64,6 @@ 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; @@ -242,15 +241,12 @@ public class Attackable extends Npc addDamage(attacker, (int) value, skill); // Check Raidboss attack. Character will be petrified if attacking a raid that's more than 8 levels lower. In retail you deal damage to raid before curse. - if (_isRaid && giveRaidCurse() && !Config.RAID_DISABLE_CURSE) + if (_isRaid && giveRaidCurse() && !Config.RAID_DISABLE_CURSE && (attacker.getLevel() > (getLevel() + 8))) { - if (attacker.getLevel() > (getLevel() + 8)) + final Skill raidCurse = CommonSkill.RAID_CURSE2.getSkill(); + if (raidCurse != null) { - final Skill raidCurse = CommonSkill.RAID_CURSE2.getSkill(); - if (raidCurse != null) - { - raidCurse.applyEffects(this, attacker); - } + raidCurse.applyEffects(this, attacker); } } } @@ -515,12 +511,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1148,64 +1144,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ @@ -1582,19 +1520,17 @@ public class Attackable extends Npc { // Reset champion state _champion = false; - if (Config.CHAMPION_ENABLE) + + // Set champion on next spawn + if (Config.CHAMPION_ENABLE && isMonster() && !isQuestMonster() && !getTemplate().isUndying() && !_isRaid && !_isRaidMinion && (Config.CHAMPION_FREQUENCY > 0) && (getLevel() >= Config.CHAMP_MIN_LEVEL) && (getLevel() <= Config.CHAMP_MAX_LEVEL) && (Config.CHAMPION_ENABLE_IN_INSTANCES || (getInstanceId() == 0))) { - // Set champion on next spawn - if (isMonster() && !isQuestMonster() && !getTemplate().isUndying() && !_isRaid && !_isRaidMinion && (Config.CHAMPION_FREQUENCY > 0) && (getLevel() >= Config.CHAMP_MIN_LEVEL) && (getLevel() <= Config.CHAMP_MAX_LEVEL) && (Config.CHAMPION_ENABLE_IN_INSTANCES || (getInstanceId() == 0))) + if (Rnd.get(100) < Config.CHAMPION_FREQUENCY) { - if (Rnd.get(100) < Config.CHAMPION_FREQUENCY) - { - _champion = true; - } - if (Config.SHOW_CHAMPION_AURA) - { - setTeam(_champion ? Team.RED : Team.NONE, false); - } + _champion = true; + } + if (Config.SHOW_CHAMPION_AURA) + { + setTeam(_champion ? Team.RED : Team.NONE, false); } } @@ -1893,12 +1829,9 @@ public class Attackable extends Npc { final WorldObject target = getTarget(); final Map aggroList = _aggroList; - if (target != null) + if ((target != null) && (aggroList != null)) { - if (aggroList != null) - { - aggroList.remove(target); - } + aggroList.remove(target); } if ((aggroList != null) && aggroList.isEmpty()) { 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/GameServer.java index 7ce154a8f1..b0b88aaff1 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -119,6 +118,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -333,7 +333,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 5f709664e1..05ad255d5a 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -63,7 +63,6 @@ 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; @@ -508,12 +507,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1141,64 +1140,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/GameServer.java index 7ce154a8f1..b0b88aaff1 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -119,6 +118,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -333,7 +333,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 5f709664e1..05ad255d5a 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -63,7 +63,6 @@ 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; @@ -508,12 +507,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1141,64 +1140,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/GameServer.java index cfc6a86bd0..5b14b267eb 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -119,6 +118,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -333,7 +333,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 5f709664e1..05ad255d5a 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -63,7 +63,6 @@ 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; @@ -508,12 +507,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1141,64 +1140,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/GameServer.java index 41d5efc11d..8cfe1d641e 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -121,6 +120,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -337,7 +337,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 d5201667ab..31da57fa98 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -62,7 +62,6 @@ 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; @@ -507,12 +506,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1127,64 +1126,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/GameServer.java index 41d5efc11d..8cfe1d641e 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -121,6 +120,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -337,7 +337,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 d5201667ab..31da57fa98 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -62,7 +62,6 @@ 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; @@ -507,12 +506,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1127,64 +1126,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/GameServer.java index 64078eee30..9279f8e200 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -122,6 +121,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -339,7 +339,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 d5201667ab..31da57fa98 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -62,7 +62,6 @@ 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; @@ -507,12 +506,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1127,64 +1126,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/GameServer.java index 1646dfe627..b0d55f5100 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -124,6 +123,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -342,7 +342,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 e3f1ee2812..9d8ddeeac5 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -62,7 +62,6 @@ 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; @@ -507,12 +506,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1138,64 +1137,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/GameServer.java index c2d4142e64..15079f96f7 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -124,6 +123,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -341,7 +341,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); HomunculusData.getInstance(); printSection("Instance"); diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/Attackable.java index e3f1ee2812..9d8ddeeac5 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -62,7 +62,6 @@ 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; @@ -507,12 +506,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1138,64 +1137,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index b6b0d60be0..1bc53fb2f5 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/GameServer.java index c3f1c3c52e..826309c04d 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -125,6 +124,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -343,7 +343,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); HomunculusData.getInstance(); printSection("Instance"); diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/actor/Attackable.java index e3f1ee2812..9d8ddeeac5 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -62,7 +62,6 @@ 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; @@ -507,12 +506,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1138,64 +1137,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ diff --git a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index b6b0d60be0..1bc53fb2f5 100644 --- a/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_9.0_ReturnOfTheQueenAnt/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/GameServer.java index c3f1c3c52e..826309c04d 100644 --- a/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.CharNameTable; @@ -125,6 +124,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FortManager; @@ -343,7 +343,7 @@ public class GameServer ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); HomunculusData.getInstance(); printSection("Instance"); diff --git a/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} diff --git a/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/model/actor/Attackable.java index e3f1ee2812..9d8ddeeac5 100644 --- a/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -62,7 +62,6 @@ 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; @@ -507,12 +506,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1138,64 +1137,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ diff --git a/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index b6b0d60be0..1bc53fb2f5 100644 --- a/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_9.2_ReturnOfTheQueenAnt_Ch2/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/GameServer.java index 37c4cd249d..4aa6b7ef14 100644 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/GameServer.java @@ -38,7 +38,6 @@ import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.AugmentationData; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.MerchantPriceConfigTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; @@ -105,6 +104,7 @@ import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager; import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FishingChampionshipManager; @@ -312,7 +312,7 @@ public class GameServer SchemeBufferTable.getInstance(); ZoneManager.getInstance(); GrandBossManager.getInstance().initZones(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Olympiad"); Olympiad.getInstance(); diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 a08bdc467f..fa89075e07 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 @@ -30,20 +30,19 @@ import java.util.logging.Level; import org.l2jmobius.Config; import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.util.Chronos; -import org.l2jmobius.commons.util.Rnd; import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.FortSiegeGuardAI; import org.l2jmobius.gameserver.ai.SiegeGuardAI; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AbsorberInfo; import org.l2jmobius.gameserver.model.AggroInfo; @@ -63,7 +62,6 @@ 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; @@ -483,12 +481,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1101,64 +1099,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 0ada6ac862..216a2a5cd7 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 @@ -37,10 +37,10 @@ import org.w3c.dom.Node; import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; @@ -57,6 +57,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; // Messages @@ -64,9 +65,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -130,8 +128,8 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if (period.length() == 21) { @@ -147,33 +145,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -330,19 +301,22 @@ public class LongTimeEvent extends Quest } } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -367,65 +341,40 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -453,4 +402,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/GameServer.java index 2dc736a90c..419f8f68c6 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/GameServer.java @@ -38,7 +38,6 @@ import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.AugmentationData; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.MerchantPriceConfigTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; @@ -106,6 +105,7 @@ import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager; import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.FishingChampionshipManager; @@ -314,7 +314,7 @@ public class GameServer SchemeBufferTable.getInstance(); ZoneManager.getInstance(); GrandBossManager.getInstance().initZones(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Olympiad"); Olympiad.getInstance(); diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 a08bdc467f..fa89075e07 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 @@ -30,20 +30,19 @@ import java.util.logging.Level; import org.l2jmobius.Config; import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.util.Chronos; -import org.l2jmobius.commons.util.Rnd; import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.FortSiegeGuardAI; import org.l2jmobius.gameserver.ai.SiegeGuardAI; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AbsorberInfo; import org.l2jmobius.gameserver.model.AggroInfo; @@ -63,7 +62,6 @@ 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; @@ -483,12 +481,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1101,64 +1099,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 0ada6ac862..216a2a5cd7 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 @@ -37,10 +37,10 @@ import org.w3c.dom.Node; import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; @@ -57,6 +57,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; // Messages @@ -64,9 +65,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -130,8 +128,8 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if (period.length() == 21) { @@ -147,33 +145,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -330,19 +301,22 @@ public class LongTimeEvent extends Quest } } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -367,65 +341,40 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -453,4 +402,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/GameServer.java index 2250579108..b2c2dc0701 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -119,6 +118,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -333,7 +333,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 c3900e3149..80d601d95d 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -63,7 +63,6 @@ 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; @@ -508,12 +507,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1141,64 +1140,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/GameServer.java index 2250579108..b2c2dc0701 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -119,6 +118,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -333,7 +333,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 c3900e3149..80d601d95d 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -63,7 +63,6 @@ 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; @@ -508,12 +507,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1141,64 +1140,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/GameServer.java index d26d52b519..930732d689 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -120,6 +119,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -335,7 +335,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 c3900e3149..80d601d95d 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -63,7 +63,6 @@ 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; @@ -508,12 +507,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1141,64 +1140,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/GameServer.java index 3b58d9fd47..130f67c84a 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -121,6 +120,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -337,7 +337,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 bfdc22d226..274b54d562 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 @@ -36,7 +36,6 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -44,6 +43,7 @@ import org.l2jmobius.gameserver.enums.ElementalType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -65,7 +65,6 @@ 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; @@ -510,12 +509,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1162,64 +1161,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/GameServer.java index 98098b97cf..178b40411e 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -122,6 +121,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -339,7 +339,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 bfdc22d226..274b54d562 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 @@ -36,7 +36,6 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -44,6 +43,7 @@ import org.l2jmobius.gameserver.enums.ElementalType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -65,7 +65,6 @@ 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; @@ -510,12 +509,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1162,64 +1161,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/GameServer.java index c063b10c13..d8ed5cf34e 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -124,6 +123,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -342,7 +342,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 bfdc22d226..274b54d562 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 @@ -36,7 +36,6 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; @@ -44,6 +43,7 @@ import org.l2jmobius.gameserver.enums.ElementalType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -65,7 +65,6 @@ 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; @@ -510,12 +509,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1162,64 +1161,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/GameServer.java index 11190810c0..13d394d27f 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -117,6 +116,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -328,7 +328,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} 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 fc47b54b5c..4869e04f3c 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 @@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.DropType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AbsorberInfo; @@ -64,7 +64,6 @@ 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; @@ -512,12 +511,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1145,64 +1144,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ 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 b6b0d60be0..1bc53fb2f5 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 @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/GameServer.java index c896f4294d..1bc81a7cb0 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -130,6 +129,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -353,7 +353,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 52175aaea1..fc831fb5ff 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -36,7 +36,6 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.xml.MagicLampData; import org.l2jmobius.gameserver.enums.ChatType; @@ -45,6 +44,7 @@ import org.l2jmobius.gameserver.enums.ElementalType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -66,7 +66,6 @@ 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; @@ -511,12 +510,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1167,64 +1166,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index b6b0d60be0..1bc53fb2f5 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/GameServer.java index d0c9296eb2..f18aefebe6 100644 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -134,6 +133,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -363,7 +363,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 0f20c0473b..edc6f375c4 100644 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -36,7 +36,6 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.xml.MagicLampData; import org.l2jmobius.gameserver.enums.ChatType; @@ -45,6 +44,7 @@ import org.l2jmobius.gameserver.enums.ElementalType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -66,7 +66,6 @@ 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; @@ -516,12 +515,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1172,64 +1171,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ diff --git a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index b6b0d60be0..1bc53fb2f5 100644 --- a/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Essence_5.0_Sylph/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } } diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/GameServer.java index d0c9296eb2..f18aefebe6 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/GameServer.java @@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector; import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.BotReportTable; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.SchemeBufferTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; @@ -134,6 +133,7 @@ import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.CustomMailManager; import org.l2jmobius.gameserver.instancemanager.DBSpawnManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.FactionManager; import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager; import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; @@ -363,7 +363,7 @@ public class GameServer CastleManager.getInstance().loadInstances(); SchemeBufferTable.getInstance(); GrandBossManager.getInstance(); - EventDroplist.getInstance(); + EventDropManager.getInstance(); printSection("Instance"); InstanceManager.getInstance(); diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/data/EventDroplist.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/data/EventDroplist.java deleted file mode 100644 index d5e089e25b..0000000000 --- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/data/EventDroplist.java +++ /dev/null @@ -1,97 +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.data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.concurrent.ConcurrentHashMap; - -import org.l2jmobius.gameserver.model.holders.EventDropHolder; -import org.l2jmobius.gameserver.script.DateRange; - -/** - * This class manage drop of Special Events created by GM for a defined period.
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops.
- * Each Special Event has a start and end date to stop to drop extra Items automatically. - */ -public class EventDroplist -{ - /** - * The table containing all DataDrop object - */ - private static final Collection ALL_NPC_DATE_DROPS = ConcurrentHashMap.newKeySet(); - - private static final class DateDrop - { - private final DateRange _dateRange; - private final EventDropHolder _eventDrop; - - public DateDrop(DateRange dateRange, EventDropHolder eventDrop) - { - _dateRange = dateRange; - _eventDrop = eventDrop; - } - - public EventDropHolder getEventDrop() - { - return _eventDrop; - } - - public DateRange getDateRange() - { - return _dateRange; - } - } - - /** - * @param dateRange the event drop rate range - * @param drop the event drop - */ - public void addGlobalDrop(DateRange dateRange, EventDropHolder drop) - { - ALL_NPC_DATE_DROPS.add(new DateDrop(dateRange, drop)); - } - - /** - * @return all DateDrop of EventDroplist allNpcDateDrops within the date range. - */ - public Collection getAllDrops() - { - final Collection list = new ArrayList<>(); - final Date currentDate = new Date(); - for (DateDrop drop : ALL_NPC_DATE_DROPS) - { - if (drop.getDateRange().isWithinRange(currentDate)) - { - list.add(drop.getEventDrop()); - } - } - return list; - } - - public static EventDroplist getInstance() - { - return SingletonHolder.INSTANCE; - } - - private static class SingletonHolder - { - protected static final EventDroplist INSTANCE = new EventDroplist(); - } -} diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java new file mode 100644 index 0000000000..efc70492fe --- /dev/null +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/EventDropManager.java @@ -0,0 +1,102 @@ +/* + * 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.instancemanager; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.util.Rnd; +import org.l2jmobius.gameserver.model.actor.Attackable; +import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; +import org.l2jmobius.gameserver.model.holders.EventDropHolder; +import org.l2jmobius.gameserver.model.quest.LongTimeEvent; + +/** + * @author Mobius + */ +public class EventDropManager +{ + private static final Map> EVENT_DROPS = new ConcurrentHashMap<>(1); + + public void addDrops(LongTimeEvent longTimeEvent, List dropList) + { + EVENT_DROPS.put(longTimeEvent, dropList); + } + + public void removeDrops(LongTimeEvent longTimeEvent) + { + EVENT_DROPS.remove(longTimeEvent); + } + + public void doEventDrop(PlayerInstance player, Attackable attackable) + { + if (EVENT_DROPS.isEmpty()) + { + return; + } + + // Event items drop only for players. + if ((player == null) || attackable.isFakePlayer()) + { + return; + } + + // Event items drop only within a 9 level difference. + if ((player.getLevel() - attackable.getLevel()) > 9) + { + return; + } + + for (List eventDrops : EVENT_DROPS.values()) + { + DROPS: for (EventDropHolder drop : eventDrops) + { + if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(attackable.getId())) + { + continue DROPS; + } + + final int monsterLevel = attackable.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 || attackable.isFlying()) + { + player.doAutoLoot(attackable, itemId, itemCount); // Give the item to the player that has killed the attackable. + } + else + { + attackable.dropItem(player, itemId, itemCount); // Drop the item on the ground. + } + } + } + } + } + + public static EventDropManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final EventDropManager INSTANCE = new EventDropManager(); + } +} diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/actor/Attackable.java index 0f20c0473b..edc6f375c4 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/actor/Attackable.java +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/actor/Attackable.java @@ -36,7 +36,6 @@ import org.l2jmobius.gameserver.ai.AttackableAI; import org.l2jmobius.gameserver.ai.CreatureAI; import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlIntention; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.xml.MagicLampData; import org.l2jmobius.gameserver.enums.ChatType; @@ -45,6 +44,7 @@ import org.l2jmobius.gameserver.enums.ElementalType; import org.l2jmobius.gameserver.enums.InstanceType; import org.l2jmobius.gameserver.enums.Team; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager; import org.l2jmobius.gameserver.instancemanager.WalkingManager; import org.l2jmobius.gameserver.model.AggroInfo; @@ -66,7 +66,6 @@ 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; @@ -516,12 +515,12 @@ public class Attackable extends Npc { PlayerInstance leader = mostDamageParty.party.getLeader(); doItemDrop(leader); - doEventDrop(leader); + EventDropManager.getInstance().doEventDrop(leader, this); } else { doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker); - doEventDrop(lastAttacker); + EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this); } if (!getMustRewardExpSP()) @@ -1172,64 +1171,6 @@ public class Attackable extends Npc } } - /** - * Manage Special Events drops created by GM for a defined period.
- * Concept:
- * During a Special Event all Attackable can drop extra Items.
- * Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.
- * Each Special Event has a start and end date to stop to drop extra Items automatically.
- * Actions: If an extra drop must be generated
- * Get an Item Identifier (random) from the DateDrop Item table of this Event.
- * Get the Item quantity dropped (random).
- * Create this or these ItemInstance corresponding to this Item Identifier.
- * If the autoLoot mode is actif and if the Creature that has killed the Attackable is a PlayerInstance, Give the item(s) to the PlayerInstance that has killed the Attackable
- * If the autoLoot mode isn't actif or if the Creature that has killed the Attackable is not a PlayerInstance, add this or these item(s) in the world as a visible object at the position where mob was last - * @param lastAttacker The Creature that has killed the Attackable - */ - public void doEventDrop(Creature lastAttacker) - { - if ((lastAttacker == null) || isFakePlayer()) - { - return; - } - - final PlayerInstance player = lastAttacker.getActingPlayer(); - - // Don't drop anything if the last attacker or owner isn't PlayerInstance - if (player == null) - { - return; - } - - if ((player.getLevel() - getLevel()) > 9) - { - return; - } - - // Go through DateDrop of EventDroplist allNpcDateDrops within the date range - for (EventDropHolder drop : EventDroplist.getInstance().getAllDrops()) - { - if (!drop.getMonsterIds().isEmpty() && !drop.getMonsterIds().contains(getId())) - { - 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 - } - else - { - dropItem(player, itemId, itemCount); // drop the item on the ground - } - } - } - } - /** * @return the active weapon of this Attackable (= null). */ diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java index b6b0d60be0..1bc53fb2f5 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/quest/LongTimeEvent.java @@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.commons.util.IXmlReader; -import org.l2jmobius.gameserver.data.EventDroplist; import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.xml.NpcData; +import org.l2jmobius.gameserver.instancemanager.EventDropManager; import org.l2jmobius.gameserver.instancemanager.EventShrineManager; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.World; @@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast; public class LongTimeEvent extends Quest { protected String _eventName; + protected DateRange _eventPeriod = null; protected boolean _active = false; protected boolean _enableShrines = false; @@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest protected String _endMsg = ""; protected int _enterAnnounceId = -1; - protected DateRange _eventPeriod = null; - protected DateRange _dropPeriod; - // NPCs to spawm and their spawn points protected final List _spawnList = new ArrayList<>(); @@ -134,8 +132,9 @@ public class LongTimeEvent extends Quest { throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!"); } - final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); + _eventName = doc.getDocumentElement().getAttributes().getNamedItem("name").getNodeValue(); + final String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue(); if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true")) { @@ -155,34 +154,6 @@ public class LongTimeEvent extends Quest _eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); } - if (doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod") != null) - { - final String dropPeriod = doc.getDocumentElement().getAttributes().getNamedItem("dropPeriod").getNodeValue(); - - if (dropPeriod.length() == 21) - { - // dd MM yyyy-dd MM yyyy - _dropPeriod = DateRange.parse(dropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - else if (dropPeriod.length() == 11) - { - // dd MM-dd MM - final String start = dropPeriod.split("-")[0].concat(" ").concat(currentYear); - final String end = dropPeriod.split("-")[1].concat(" ").concat(currentYear); - final String activeDropPeriod = start.concat("-").concat(end); - _dropPeriod = DateRange.parse(activeDropPeriod, new SimpleDateFormat("dd MM yyyy", Locale.US)); - } - // Check if drop period is within range of event period - if (!_eventPeriod.isWithinRange(_dropPeriod.getStartDate()) || !_eventPeriod.isWithinRange(_dropPeriod.getEndDate())) - { - _dropPeriod = _eventPeriod; - } - } - else - { - _dropPeriod = _eventPeriod; // Drop period, if not specified, assumes all event period. - } - if (_eventPeriod == null) { throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period"); @@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest } - /** - * Maintenance event start - adds global drop, spawns event NPCs, shows start announcement. - */ + protected class ScheduleStart implements Runnable + { + @Override + public void run() + { + startEvent(); + } + } + protected void startEvent() { // Set Active. _active = true; - // Add drop. - for (EventDropHolder drop : _dropList) - { - EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop); - } + // Add event drops. + EventDropManager.getInstance().addDrops(this, _dropList); // Add spawns. final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis(); @@ -380,71 +354,46 @@ public class LongTimeEvent extends Quest ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd); } - /** - * @return event period - */ - public DateRange getEventPeriod() - { - return _eventPeriod; - } - - /** - * @return {@code true} if now is event period - */ - public boolean isEventPeriod() - { - return _active; - } - - /** - * @return {@code true} if now is drop period - */ - public boolean isDropPeriod() - { - return _dropPeriod.isWithinRange(new Date()); - } - - protected class ScheduleStart implements Runnable - { - @Override - public void run() - { - startEvent(); - } - } - protected class ScheduleEnd implements Runnable { @Override public void run() { - // Set Active. - _active = false; - - // Disable town shrines. - if (_enableShrines) - { - EventShrineManager.getInstance().setEnabled(false); - } - - // Destroy items that must exist only on event period. - destroyItemsOnEnd(); - - // Send message on end. - if (!_endMsg.isEmpty()) - { - Broadcast.toAllOnlinePlayers(_endMsg); - } - - // Remove announce for entering players. - if (_enterAnnounceId != -1) - { - AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); - } + stopEvent(); } } - void destroyItemsOnEnd() + protected void stopEvent() + { + // Set Active. + _active = false; + + // Stop event drops. + EventDropManager.getInstance().removeDrops(this); + + // Disable town shrines. + if (_enableShrines) + { + EventShrineManager.getInstance().setEnabled(false); + } + + // Destroy items that must exist only on event period. + destroyItemsOnEnd(); + + // Send message on end. + if (!_endMsg.isEmpty()) + { + Broadcast.toAllOnlinePlayers(_endMsg); + } + + // Remove announce for entering players. + if (_enterAnnounceId != -1) + { + AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId); + } + } + + protected void destroyItemsOnEnd() { if (!_destroyItemsOnEnd.isEmpty()) { @@ -472,4 +421,17 @@ public class LongTimeEvent extends Quest } } } + + public DateRange getEventPeriod() + { + return _eventPeriod; + } + + /** + * @return {@code true} if now is event period + */ + public boolean isEventPeriod() + { + return _active; + } }