Addition of EventDropManager class.

This commit is contained in:
MobiusDevelopment
2021-07-22 11:03:19 +00:00
parent 0e745ad289
commit 2dcb626712
115 changed files with 3842 additions and 5968 deletions

View File

@@ -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();

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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.<br>
* During a Special Event all Attackable can drop extra Items.<br>
* Those extra Items are defined in the table <b>allNpcDateDrops</b>.<br>
* 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<DateDrop> 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<EventDropHolder> getAllDrops()
{
final Collection<EventDropHolder> 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();
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<LongTimeEvent, List<EventDropHolder>> EVENT_DROPS = new ConcurrentHashMap<>(1);
public void addDrops(LongTimeEvent longTimeEvent, List<EventDropHolder> 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<EventDropHolder> 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();
}
}

View File

@@ -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.<br>
* Concept:<br>
* During a Special Event all Attackable can drop extra Items.<br>
* Those extra Items are defined in the table allNpcDateDrops of the EventDroplist.<br>
* Each Special Event has a start and end date to stop to drop extra Items automatically.<br>
* Actions: <i>If an extra drop must be generated</i><br>
* Get an Item Identifier (random) from the DateDrop Item table of this Event.<br>
* Get the Item quantity dropped (random).<br>
* Create this or these ItemInstance corresponding to this Item Identifier.<br>
* 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<br>
* 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).
*/

View File

@@ -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<NpcSpawn> _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;
}
}