Addition of EventDropManager class.
This commit is contained in:
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -325,7 +325,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AbsorberInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -242,9 +241,7 @@ public class Attackable extends Npc
|
|||||||
addDamage(attacker, (int) value, skill);
|
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.
|
// 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();
|
final Skill raidCurse = CommonSkill.RAID_CURSE2.getSkill();
|
||||||
if (raidCurse != null)
|
if (raidCurse != null)
|
||||||
@@ -253,7 +250,6 @@ public class Attackable extends Npc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If this Attackable is a MonsterInstance and it has spawned minions, call its minions to battle
|
// If this Attackable is a MonsterInstance and it has spawned minions, call its minions to battle
|
||||||
if (isMonster())
|
if (isMonster())
|
||||||
@@ -515,12 +511,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1148,64 +1144,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
@@ -1582,10 +1520,9 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
// Reset champion state
|
// Reset champion state
|
||||||
_champion = false;
|
_champion = false;
|
||||||
if (Config.CHAMPION_ENABLE)
|
|
||||||
{
|
|
||||||
// Set champion on next spawn
|
// 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 (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)))
|
||||||
{
|
{
|
||||||
if (Rnd.get(100) < Config.CHAMPION_FREQUENCY)
|
if (Rnd.get(100) < Config.CHAMPION_FREQUENCY)
|
||||||
{
|
{
|
||||||
@@ -1596,7 +1533,6 @@ public class Attackable extends Npc
|
|||||||
setTeam(_champion ? Team.RED : Team.NONE, false);
|
setTeam(_champion ? Team.RED : Team.NONE, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the rest of NPC related states
|
// Reset the rest of NPC related states
|
||||||
super.onRespawn();
|
super.onRespawn();
|
||||||
@@ -1893,13 +1829,10 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
final WorldObject target = getTarget();
|
final WorldObject target = getTarget();
|
||||||
final Map<Creature, AggroInfo> aggroList = _aggroList;
|
final Map<Creature, AggroInfo> aggroList = _aggroList;
|
||||||
if (target != null)
|
if ((target != null) && (aggroList != null))
|
||||||
{
|
|
||||||
if (aggroList != null)
|
|
||||||
{
|
{
|
||||||
aggroList.remove(target);
|
aggroList.remove(target);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ((aggroList != null) && aggroList.isEmpty())
|
if ((aggroList != null) && aggroList.isEmpty())
|
||||||
{
|
{
|
||||||
if (getAI() instanceof AttackableAI)
|
if (getAI() instanceof AttackableAI)
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -333,7 +333,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -508,12 +507,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1141,64 +1140,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -333,7 +333,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -508,12 +507,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1141,64 +1140,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -333,7 +333,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -508,12 +507,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1141,64 +1140,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -337,7 +337,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -507,12 +506,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1127,64 +1126,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -337,7 +337,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -507,12 +506,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1127,64 +1126,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -339,7 +339,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -507,12 +506,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1127,64 +1126,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -342,7 +342,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -507,12 +506,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1138,64 +1137,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -341,7 +341,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
HomunculusData.getInstance();
|
HomunculusData.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -507,12 +506,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1138,64 +1137,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -343,7 +343,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
HomunculusData.getInstance();
|
HomunculusData.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -507,12 +506,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1138,64 +1137,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.CharNameTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
import org.l2jmobius.gameserver.instancemanager.FortManager;
|
||||||
@@ -343,7 +343,7 @@ public class GameServer
|
|||||||
ItemAuctionManager.getInstance();
|
ItemAuctionManager.getInstance();
|
||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
HomunculusData.getInstance();
|
HomunculusData.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -507,12 +506,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1138,64 +1137,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import org.l2jmobius.commons.util.PropertiesParser;
|
|||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.AugmentationData;
|
import org.l2jmobius.gameserver.data.AugmentationData;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.MerchantPriceConfigTable;
|
import org.l2jmobius.gameserver.data.MerchantPriceConfigTable;
|
||||||
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
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.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager;
|
import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FishingChampionshipManager;
|
import org.l2jmobius.gameserver.instancemanager.FishingChampionshipManager;
|
||||||
@@ -312,7 +312,7 @@ public class GameServer
|
|||||||
SchemeBufferTable.getInstance();
|
SchemeBufferTable.getInstance();
|
||||||
ZoneManager.getInstance();
|
ZoneManager.getInstance();
|
||||||
GrandBossManager.getInstance().initZones();
|
GrandBossManager.getInstance().initZones();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Olympiad");
|
printSection("Olympiad");
|
||||||
Olympiad.getInstance();
|
Olympiad.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,20 +30,19 @@ import java.util.logging.Level;
|
|||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
import org.l2jmobius.commons.concurrent.ThreadPool;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.Rnd;
|
|
||||||
import org.l2jmobius.gameserver.ai.AttackableAI;
|
import org.l2jmobius.gameserver.ai.AttackableAI;
|
||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.ai.FortSiegeGuardAI;
|
import org.l2jmobius.gameserver.ai.FortSiegeGuardAI;
|
||||||
import org.l2jmobius.gameserver.ai.SiegeGuardAI;
|
import org.l2jmobius.gameserver.ai.SiegeGuardAI;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AbsorberInfo;
|
import org.l2jmobius.gameserver.model.AbsorberInfo;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.attackable.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -483,12 +481,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1101,64 +1099,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ import org.w3c.dom.Node;
|
|||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
import org.l2jmobius.commons.concurrent.ThreadPool;
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
@@ -57,6 +57,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
@@ -64,9 +65,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
||||||
|
|
||||||
@@ -130,8 +128,8 @@ public class LongTimeEvent extends Quest
|
|||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if (period.length() == 21)
|
if (period.length() == 21)
|
||||||
{
|
{
|
||||||
@@ -147,33 +145,6 @@ public class LongTimeEvent extends Quest
|
|||||||
_eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -330,19 +301,22 @@ public class LongTimeEvent extends Quest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -367,47 +341,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Destroy items that must exist only on event period.
|
// Destroy items that must exist only on event period.
|
||||||
destroyItemsOnEnd();
|
destroyItemsOnEnd();
|
||||||
|
|
||||||
@@ -423,9 +373,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import org.l2jmobius.commons.util.PropertiesParser;
|
|||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.AugmentationData;
|
import org.l2jmobius.gameserver.data.AugmentationData;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.MerchantPriceConfigTable;
|
import org.l2jmobius.gameserver.data.MerchantPriceConfigTable;
|
||||||
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
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.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager;
|
import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FishingChampionshipManager;
|
import org.l2jmobius.gameserver.instancemanager.FishingChampionshipManager;
|
||||||
@@ -314,7 +314,7 @@ public class GameServer
|
|||||||
SchemeBufferTable.getInstance();
|
SchemeBufferTable.getInstance();
|
||||||
ZoneManager.getInstance();
|
ZoneManager.getInstance();
|
||||||
GrandBossManager.getInstance().initZones();
|
GrandBossManager.getInstance().initZones();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Olympiad");
|
printSection("Olympiad");
|
||||||
Olympiad.getInstance();
|
Olympiad.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,20 +30,19 @@ import java.util.logging.Level;
|
|||||||
import org.l2jmobius.Config;
|
import org.l2jmobius.Config;
|
||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
import org.l2jmobius.commons.concurrent.ThreadPool;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.Rnd;
|
|
||||||
import org.l2jmobius.gameserver.ai.AttackableAI;
|
import org.l2jmobius.gameserver.ai.AttackableAI;
|
||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.ai.FortSiegeGuardAI;
|
import org.l2jmobius.gameserver.ai.FortSiegeGuardAI;
|
||||||
import org.l2jmobius.gameserver.ai.SiegeGuardAI;
|
import org.l2jmobius.gameserver.ai.SiegeGuardAI;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AbsorberInfo;
|
import org.l2jmobius.gameserver.model.AbsorberInfo;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.attackable.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -483,12 +481,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1101,64 +1099,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ import org.w3c.dom.Node;
|
|||||||
import org.l2jmobius.commons.concurrent.ThreadPool;
|
import org.l2jmobius.commons.concurrent.ThreadPool;
|
||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
@@ -57,6 +57,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
@@ -64,9 +65,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
||||||
|
|
||||||
@@ -130,8 +128,8 @@ public class LongTimeEvent extends Quest
|
|||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getScriptName() + " event: bad config file!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if (period.length() == 21)
|
if (period.length() == 21)
|
||||||
{
|
{
|
||||||
@@ -147,33 +145,6 @@ public class LongTimeEvent extends Quest
|
|||||||
_eventPeriod = DateRange.parse(activePeriod, new SimpleDateFormat("dd MM yyyy", Locale.US));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -330,19 +301,22 @@ public class LongTimeEvent extends Quest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -367,47 +341,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Destroy items that must exist only on event period.
|
// Destroy items that must exist only on event period.
|
||||||
destroyItemsOnEnd();
|
destroyItemsOnEnd();
|
||||||
|
|
||||||
@@ -423,9 +373,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||||
@@ -333,7 +333,7 @@ public class GameServer
|
|||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
SchemeBufferTable.getInstance();
|
SchemeBufferTable.getInstance();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -508,12 +507,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1141,64 +1140,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||||
@@ -333,7 +333,7 @@ public class GameServer
|
|||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
SchemeBufferTable.getInstance();
|
SchemeBufferTable.getInstance();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -508,12 +507,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1141,64 +1140,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||||
@@ -335,7 +335,7 @@ public class GameServer
|
|||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
SchemeBufferTable.getInstance();
|
SchemeBufferTable.getInstance();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -508,12 +507,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1141,64 +1140,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||||
@@ -337,7 +337,7 @@ public class GameServer
|
|||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
SchemeBufferTable.getInstance();
|
SchemeBufferTable.getInstance();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,6 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
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.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -510,12 +509,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||||
@@ -339,7 +339,7 @@ public class GameServer
|
|||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
SchemeBufferTable.getInstance();
|
SchemeBufferTable.getInstance();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,6 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
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.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -510,12 +509,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||||
@@ -342,7 +342,7 @@ public class GameServer
|
|||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
SchemeBufferTable.getInstance();
|
SchemeBufferTable.getInstance();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,6 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
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.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AggroInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -510,12 +509,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.l2jmobius.commons.util.DeadLockDetector;
|
|||||||
import org.l2jmobius.commons.util.PropertiesParser;
|
import org.l2jmobius.commons.util.PropertiesParser;
|
||||||
import org.l2jmobius.gameserver.cache.HtmCache;
|
import org.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import org.l2jmobius.gameserver.data.BotReportTable;
|
import org.l2jmobius.gameserver.data.BotReportTable;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
import org.l2jmobius.gameserver.data.SchemeBufferTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
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.CursedWeaponsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
import org.l2jmobius.gameserver.instancemanager.CustomMailManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
import org.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
import org.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
import org.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||||
@@ -328,7 +328,7 @@ public class GameServer
|
|||||||
CastleManager.getInstance().loadInstances();
|
CastleManager.getInstance().loadInstances();
|
||||||
SchemeBufferTable.getInstance();
|
SchemeBufferTable.getInstance();
|
||||||
GrandBossManager.getInstance();
|
GrandBossManager.getInstance();
|
||||||
EventDroplist.getInstance();
|
EventDropManager.getInstance();
|
||||||
|
|
||||||
printSection("Instance");
|
printSection("Instance");
|
||||||
InstanceManager.getInstance();
|
InstanceManager.getInstance();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,13 +36,13 @@ import org.l2jmobius.gameserver.ai.AttackableAI;
|
|||||||
import org.l2jmobius.gameserver.ai.CreatureAI;
|
import org.l2jmobius.gameserver.ai.CreatureAI;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||||
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.enums.ChatType;
|
import org.l2jmobius.gameserver.enums.ChatType;
|
||||||
import org.l2jmobius.gameserver.enums.DropType;
|
import org.l2jmobius.gameserver.enums.DropType;
|
||||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import org.l2jmobius.gameserver.enums.Team;
|
import org.l2jmobius.gameserver.enums.Team;
|
||||||
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
import org.l2jmobius.gameserver.instancemanager.PcCafePointsManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
import org.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||||
import org.l2jmobius.gameserver.model.AbsorberInfo;
|
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.OnAttackableAggroRangeEnter;
|
||||||
import org.l2jmobius.gameserver.model.events.impl.creature.npc.OnAttackableAttack;
|
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.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.ItemHolder;
|
||||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.items.Item;
|
import org.l2jmobius.gameserver.model.items.Item;
|
||||||
@@ -512,12 +511,12 @@ public class Attackable extends Npc
|
|||||||
{
|
{
|
||||||
PlayerInstance leader = mostDamageParty.party.getLeader();
|
PlayerInstance leader = mostDamageParty.party.getLeader();
|
||||||
doItemDrop(leader);
|
doItemDrop(leader);
|
||||||
doEventDrop(leader);
|
EventDropManager.getInstance().doEventDrop(leader, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
|
||||||
doEventDrop(lastAttacker);
|
EventDropManager.getInstance().doEventDrop(lastAttacker.getActingPlayer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getMustRewardExpSP())
|
if (!getMustRewardExpSP())
|
||||||
@@ -1145,64 +1144,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).
|
* @return the active weapon of this Attackable (= null).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
|||||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||||
import org.l2jmobius.commons.util.Chronos;
|
import org.l2jmobius.commons.util.Chronos;
|
||||||
import org.l2jmobius.commons.util.IXmlReader;
|
import org.l2jmobius.commons.util.IXmlReader;
|
||||||
import org.l2jmobius.gameserver.data.EventDroplist;
|
|
||||||
import org.l2jmobius.gameserver.data.ItemTable;
|
import org.l2jmobius.gameserver.data.ItemTable;
|
||||||
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
import org.l2jmobius.gameserver.data.sql.AnnouncementsTable;
|
||||||
import org.l2jmobius.gameserver.data.xml.NpcData;
|
import org.l2jmobius.gameserver.data.xml.NpcData;
|
||||||
|
import org.l2jmobius.gameserver.instancemanager.EventDropManager;
|
||||||
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import org.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import org.l2jmobius.gameserver.model.Location;
|
import org.l2jmobius.gameserver.model.Location;
|
||||||
import org.l2jmobius.gameserver.model.World;
|
import org.l2jmobius.gameserver.model.World;
|
||||||
@@ -55,6 +55,7 @@ import org.l2jmobius.gameserver.util.Broadcast;
|
|||||||
public class LongTimeEvent extends Quest
|
public class LongTimeEvent extends Quest
|
||||||
{
|
{
|
||||||
protected String _eventName;
|
protected String _eventName;
|
||||||
|
protected DateRange _eventPeriod = null;
|
||||||
protected boolean _active = false;
|
protected boolean _active = false;
|
||||||
protected boolean _enableShrines = false;
|
protected boolean _enableShrines = false;
|
||||||
|
|
||||||
@@ -63,9 +64,6 @@ public class LongTimeEvent extends Quest
|
|||||||
protected String _endMsg = "";
|
protected String _endMsg = "";
|
||||||
protected int _enterAnnounceId = -1;
|
protected int _enterAnnounceId = -1;
|
||||||
|
|
||||||
protected DateRange _eventPeriod = null;
|
|
||||||
protected DateRange _dropPeriod;
|
|
||||||
|
|
||||||
// NPCs to spawm and their spawn points
|
// NPCs to spawm and their spawn points
|
||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
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!");
|
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();
|
_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();
|
final String period = doc.getDocumentElement().getAttributes().getNamedItem("active").getNodeValue();
|
||||||
if ((doc.getDocumentElement().getAttributes().getNamedItem("enableShrines") != null) && doc.getDocumentElement().getAttributes().getNamedItem("enableShrines").getNodeValue().equalsIgnoreCase("true"))
|
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));
|
_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)
|
if (_eventPeriod == null)
|
||||||
{
|
{
|
||||||
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
throw new NullPointerException("WARNING!!! " + getName() + " event: illegal event period");
|
||||||
@@ -337,19 +308,22 @@ public class LongTimeEvent extends Quest
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected class ScheduleStart implements Runnable
|
||||||
* Maintenance event start - adds global drop, spawns event NPCs, shows start announcement.
|
{
|
||||||
*/
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
startEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void startEvent()
|
protected void startEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
// Add drop.
|
// Add event drops.
|
||||||
for (EventDropHolder drop : _dropList)
|
EventDropManager.getInstance().addDrops(this, _dropList);
|
||||||
{
|
|
||||||
EventDroplist.getInstance().addGlobalDrop(_dropPeriod, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spawns.
|
// Add spawns.
|
||||||
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
final Long millisToEventEnd = _eventPeriod.getEndDate().getTime() - Chronos.currentTimeMillis();
|
||||||
@@ -380,47 +354,23 @@ public class LongTimeEvent extends Quest
|
|||||||
ThreadPool.schedule(new ScheduleEnd(), millisToEventEnd);
|
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
|
protected class ScheduleEnd implements Runnable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
{
|
||||||
|
stopEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopEvent()
|
||||||
{
|
{
|
||||||
// Set Active.
|
// Set Active.
|
||||||
_active = false;
|
_active = false;
|
||||||
|
|
||||||
|
// Stop event drops.
|
||||||
|
EventDropManager.getInstance().removeDrops(this);
|
||||||
|
|
||||||
// Disable town shrines.
|
// Disable town shrines.
|
||||||
if (_enableShrines)
|
if (_enableShrines)
|
||||||
{
|
{
|
||||||
@@ -442,9 +392,8 @@ public class LongTimeEvent extends Quest
|
|||||||
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
AnnouncementsTable.getInstance().deleteAnnouncement(_enterAnnounceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void destroyItemsOnEnd()
|
protected void destroyItemsOnEnd()
|
||||||
{
|
{
|
||||||
if (!_destroyItemsOnEnd.isEmpty())
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user