Drops rework.

This commit is contained in:
MobiusDev
2017-10-06 00:53:49 +00:00
parent 2c61857b12
commit fc94704b2d
408 changed files with 741952 additions and 835872 deletions

View File

@@ -118,7 +118,6 @@ public final class Config
public static final String CUSTOM_FIND_PVP_CONFIG_FILE = "./config/Custom/FindPvP.ini";
public static final String CUSTOM_MULTILANGUAL_SUPPORT_CONFIG_FILE = "./config/Custom/MultilingualSupport.ini";
public static final String CUSTOM_OFFLINE_TRADE_CONFIG_FILE = "./config/Custom/OfflineTrade.ini";
public static final String CUSTOM_OLD_DROP_BEHAVIOR_CONFIG_FILE = "./config/Custom/OldDropBehavior.ini";
public static final String CUSTOM_PASSWORD_CHANGE_CONFIG_FILE = "./config/Custom/PasswordChange.ini";
public static final String CUSTOM_PC_CAFE_CONFIG_FILE = "./config/Custom/PcCafe.ini";
public static final String CUSTOM_PREMIUM_SYSTEM_CONFIG_FILE = "./config/Custom/PremiumSystem.ini";
@@ -452,7 +451,6 @@ public final class Config
public static boolean ORDER_QUEST_LIST_BY_QUESTID;
public static boolean AUTODELETE_INVALID_QUEST_DATA;
public static boolean ENABLE_STORY_QUEST_BUFF_REWARD;
public static boolean PRECISE_DROP_CALCULATION;
public static boolean MULTIPLE_ITEM_DROP;
public static boolean FORCE_INVENTORY_UPDATE;
public static boolean LAZY_CACHE;
@@ -696,11 +694,11 @@ public final class Config
public static float RATE_QUEST_REWARD_RECIPE;
public static float RATE_QUEST_REWARD_MATERIAL;
public static float RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
public static float RATE_CORPSE_DROP_AMOUNT_MULTIPLIER;
public static float RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
public static float RATE_HERB_DROP_AMOUNT_MULTIPLIER;
public static float RATE_RAID_DROP_AMOUNT_MULTIPLIER;
public static float RATE_DEATH_DROP_CHANCE_MULTIPLIER;
public static float RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
public static float RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
public static float RATE_HERB_DROP_CHANCE_MULTIPLIER;
public static float RATE_RAID_DROP_CHANCE_MULTIPLIER;
public static Map<Integer, Float> RATE_DROP_AMOUNT_BY_ID;
@@ -1054,7 +1052,6 @@ public final class Config
public static int DUALBOX_CHECK_MAX_L2EVENT_PARTICIPANTS_PER_IP;
public static Map<Integer, Integer> DUALBOX_CHECK_WHITELIST;
public static boolean ALLOW_CHANGE_PASSWORD;
public static boolean OLD_DROP_BEHAVIOR;
public static boolean ALLOW_HUMAN;
public static boolean ALLOW_ELF;
public static boolean ALLOW_DARKELF;
@@ -1956,14 +1953,6 @@ public final class Config
PET_HP_REGEN_MULTIPLIER = NPC.getDouble("PetHpRegenMultiplier", 100) / 100;
PET_MP_REGEN_MULTIPLIER = NPC.getDouble("PetMpRegenMultiplier", 100) / 100;
DROP_ADENA_MIN_LEVEL_DIFFERENCE = NPC.getInt("DropAdenaMinLevelDifference", 8);
DROP_ADENA_MAX_LEVEL_DIFFERENCE = NPC.getInt("DropAdenaMaxLevelDifference", 15);
DROP_ADENA_MIN_LEVEL_GAP_CHANCE = NPC.getDouble("DropAdenaMinLevelGapChance", 10);
DROP_ITEM_MIN_LEVEL_DIFFERENCE = NPC.getInt("DropItemMinLevelDifference", 5);
DROP_ITEM_MAX_LEVEL_DIFFERENCE = NPC.getInt("DropItemMaxLevelDifference", 10);
DROP_ITEM_MIN_LEVEL_GAP_CHANCE = NPC.getDouble("DropItemMinLevelGapChance", 10);
VITALITY_CONSUME_BY_MOB = NPC.getInt("VitalityConsumeByMob", 2250);
VITALITY_CONSUME_BY_BOSS = NPC.getInt("VitalityConsumeByBoss", 1125);
@@ -2036,11 +2025,11 @@ public final class Config
KARMA_RATE_DROP_EQUIP_WEAPON = RatesSettings.getInt("KarmaRateDropEquipWeapon", 10);
RATE_DEATH_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("DeathDropAmountMultiplier", 1);
RATE_CORPSE_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("CorpseDropAmountMultiplier", 1);
RATE_SPOIL_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("SpoilDropAmountMultiplier", 1);
RATE_HERB_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("HerbDropAmountMultiplier", 1);
RATE_RAID_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("RaidDropAmountMultiplier", 1);
RATE_DEATH_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("DeathDropChanceMultiplier", 1);
RATE_CORPSE_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("CorpseDropChanceMultiplier", 1);
RATE_SPOIL_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("SpoilDropChanceMultiplier", 1);
RATE_HERB_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("HerbDropChanceMultiplier", 1);
RATE_RAID_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("RaidDropChanceMultiplier", 1);
@@ -2100,6 +2089,13 @@ public final class Config
}
}
DROP_ADENA_MIN_LEVEL_DIFFERENCE = RatesSettings.getInt("DropAdenaMinLevelDifference", 8);
DROP_ADENA_MAX_LEVEL_DIFFERENCE = RatesSettings.getInt("DropAdenaMaxLevelDifference", 15);
DROP_ADENA_MIN_LEVEL_GAP_CHANCE = RatesSettings.getDouble("DropAdenaMinLevelGapChance", 10);
DROP_ITEM_MIN_LEVEL_DIFFERENCE = RatesSettings.getInt("DropItemMinLevelDifference", 5);
DROP_ITEM_MAX_LEVEL_DIFFERENCE = RatesSettings.getInt("DropItemMaxLevelDifference", 10);
DROP_ITEM_MIN_LEVEL_GAP_CHANCE = RatesSettings.getDouble("DropItemMinLevelGapChance", 10);
// Load PvP config file (if exists)
final PropertiesParser PVPSettings = new PropertiesParser(PVP_CONFIG_FILE);
@@ -2499,11 +2495,6 @@ public final class Config
OFFLINE_DISCONNECT_FINISHED = OfflineTrade.getBoolean("OfflineDisconnectFinished", true);
STORE_OFFLINE_TRADE_IN_REALTIME = OfflineTrade.getBoolean("StoreOfflineTradeInRealtime", true);
// Load OldDropBehavior config file (if exists)
final PropertiesParser OldDropBehavior = new PropertiesParser(CUSTOM_OLD_DROP_BEHAVIOR_CONFIG_FILE);
OLD_DROP_BEHAVIOR = OldDropBehavior.getBoolean("OldDropBehavior", false);
// Load PasswordChange config file (if exists)
final PropertiesParser PasswordChange = new PropertiesParser(CUSTOM_PASSWORD_CHANGE_CONFIG_FILE);

View File

@@ -39,16 +39,14 @@ import com.l2jmobius.commons.util.CommonUtil;
import com.l2jmobius.commons.util.IGameXmlReader;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.AISkillScope;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.enums.MpRewardAffectType;
import com.l2jmobius.gameserver.enums.MpRewardType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.drops.GeneralDropItem;
import com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem;
import com.l2jmobius.gameserver.model.drops.IDropItem;
import com.l2jmobius.gameserver.model.effects.L2EffectType;
import com.l2jmobius.gameserver.model.holders.DropHolder;
import com.l2jmobius.gameserver.model.skills.Skill;
/**
@@ -104,7 +102,7 @@ public class NpcData implements IGameXmlReader
Map<Integer, Skill> skills = null;
Set<Integer> clans = null;
Set<Integer> ignoreClanNpcIds = null;
Map<DropListScope, List<IDropItem>> dropLists = null;
List<DropHolder> dropLists = null;
set.set("id", npcId);
set.set("displayId", parseInteger(attrs, "displayId"));
set.set("level", parseByte(attrs, "level"));
@@ -426,26 +424,39 @@ public class NpcData implements IGameXmlReader
{
for (Node drop_lists_node = npc_node.getFirstChild(); drop_lists_node != null; drop_lists_node = drop_lists_node.getNextSibling())
{
DropListScope dropListScope = null;
DropType dropType = null;
try
{
dropListScope = Enum.valueOf(DropListScope.class, drop_lists_node.getNodeName().toUpperCase());
dropType = Enum.valueOf(DropType.class, drop_lists_node.getNodeName().toUpperCase());
}
catch (Exception e)
{
}
if (dropListScope != null)
if (dropType != null)
{
if (dropLists == null)
{
dropLists = new EnumMap<>(DropListScope.class);
dropLists = new ArrayList<>();
}
final List<IDropItem> dropList = new ArrayList<>();
parseDropList(f, drop_lists_node, dropListScope, dropList);
dropLists.put(dropListScope, Collections.unmodifiableList(dropList));
for (Node drop_node = drop_lists_node.getFirstChild(); drop_node != null; drop_node = drop_node.getNextSibling())
{
final NamedNodeMap drop_attrs = drop_node.getAttributes();
if ("item".equals(drop_node.getNodeName().toLowerCase()))
{
final DropHolder dropItem = new DropHolder(dropType, parseInteger(drop_attrs, "id"), parseLong(drop_attrs, "min"), parseLong(drop_attrs, "max"), parseDouble(drop_attrs, "chance"));
if (ItemTable.getInstance().getTemplate(parseInteger(drop_attrs, "id")) == null)
{
LOGGER.warning("DropListItem: Could not find item with id " + parseInteger(drop_attrs, "id") + ".");
}
else
{
dropLists.add(dropItem);
}
}
}
}
}
break;
@@ -611,7 +622,26 @@ public class NpcData implements IGameXmlReader
template.setClans(clans);
template.setIgnoreClanNpcIds(ignoreClanNpcIds);
template.setDropLists(dropLists);
if (dropLists != null)
{
for (DropHolder dropHolder : dropLists)
{
switch (dropHolder.getDropType())
{
case DROP:
case LUCKY_DROP: // TODO: Luck is added to death drops.
{
template.addDrop(dropHolder);
break;
}
case SPOIL:
{
template.addSpoil(dropHolder);
break;
}
}
}
}
if (!template.getParameters().getMinionList("Privates").isEmpty())
{
@@ -626,69 +656,6 @@ public class NpcData implements IGameXmlReader
}
}
private void parseDropList(File f, Node drop_list_node, DropListScope dropListScope, List<IDropItem> drops)
{
for (Node drop_node = drop_list_node.getFirstChild(); drop_node != null; drop_node = drop_node.getNextSibling())
{
final NamedNodeMap attrs = drop_node.getAttributes();
switch (drop_node.getNodeName().toLowerCase())
{
case "group":
{
final GroupedGeneralDropItem dropItem = dropListScope.newGroupedDropItem(parseDouble(attrs, "chance"));
final List<IDropItem> groupedDropList = new ArrayList<>(2);
for (Node group_node = drop_node.getFirstChild(); group_node != null; group_node = group_node.getNextSibling())
{
parseDropListItem(group_node, dropListScope, groupedDropList);
}
final List<GeneralDropItem> items = new ArrayList<>(groupedDropList.size());
for (IDropItem item : groupedDropList)
{
if (item instanceof GeneralDropItem)
{
items.add((GeneralDropItem) item);
}
else
{
LOGGER.warning("[" + f + "] grouped general drop item supports only general drop item.");
}
}
dropItem.setItems(items);
drops.add(dropItem);
break;
}
default:
{
parseDropListItem(drop_node, dropListScope, drops);
break;
}
}
}
}
private void parseDropListItem(Node drop_list_item, DropListScope dropListScope, List<IDropItem> drops)
{
final NamedNodeMap attrs = drop_list_item.getAttributes();
switch (drop_list_item.getNodeName().toLowerCase())
{
case "item":
{
final IDropItem dropItem = dropListScope.newDropItem(parseInteger(attrs, "id"), parseLong(attrs, "min"), parseLong(attrs, "max"), parseDouble(attrs, "chance"));
if (ItemTable.getInstance().getTemplate(parseInteger(attrs, "id")) == null)
{
LOGGER.warning("DropListItem: Could not find item with id " + parseInteger(attrs, "id") + ".");
}
else if (dropItem != null)
{
drops.add(dropItem);
}
break;
}
}
}
/**
* Gets or creates a clan id if it doesnt exists.
* @param clanName the clan name to get or create its id

View File

@@ -1,36 +1,27 @@
/*
* 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 com.l2jmobius.gameserver.model.drops;
import java.util.Collection;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
/**
* @author NosBit
*/
public interface IDropItem
{
/**
* Calculates drops of this drop item.
* @param victim the victim
* @param killer the killer
* @return {@code null} or empty collection if there are no drops, a collection containing all items to drop otherwise
*/
Collection<ItemHolder> calculateDrops(L2Character victim, L2Character killer);
}
/*
* 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 com.l2jmobius.gameserver.enums;
/**
* @author Mobius
*/
public enum DropType
{
DROP,
SPOIL,
LUCKY_DROP;
}

View File

@@ -45,6 +45,7 @@ import com.l2jmobius.gameserver.datatables.EventDroplist;
import com.l2jmobius.gameserver.datatables.EventDroplist.DateDrop;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.enums.Team;
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
@@ -64,7 +65,6 @@ import com.l2jmobius.gameserver.model.actor.instance.L2ServitorInstance;
import com.l2jmobius.gameserver.model.actor.status.AttackableStatus;
import com.l2jmobius.gameserver.model.actor.tasks.attackable.CommandChannelTimer;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.entity.Hero;
import com.l2jmobius.gameserver.model.events.EventDispatcher;
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnAttackableAggroRangeEnter;
@@ -974,10 +974,10 @@ public class L2Attackable extends L2Npc
if (isSpoiled())
{
_sweepItems.set(npcTemplate.calculateDrops(DropListScope.CORPSE, this, player));
_sweepItems.set(npcTemplate.calculateDrops(DropType.SPOIL, this, player));
}
final Collection<ItemHolder> deathItems = npcTemplate.calculateDrops(DropListScope.DEATH, this, player);
final Collection<ItemHolder> deathItems = npcTemplate.calculateDrops(DropType.DROP, this, player);
if (deathItems != null)
{
for (ItemHolder drop : deathItems)

View File

@@ -19,15 +19,17 @@ package com.l2jmobius.gameserver.model.actor.templates;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.AISkillScope;
import com.l2jmobius.gameserver.enums.AIType;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.enums.MpRewardAffectType;
import com.l2jmobius.gameserver.enums.MpRewardType;
import com.l2jmobius.gameserver.enums.Race;
@@ -35,11 +37,13 @@ import com.l2jmobius.gameserver.enums.Sex;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.drops.IDropItem;
import com.l2jmobius.gameserver.model.holders.DropHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.interfaces.IIdentifiable;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.util.Util;
/**
* NPC template.
@@ -96,7 +100,8 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
private Map<AISkillScope, List<Skill>> _aiSkillLists;
private Set<Integer> _clans;
private Set<Integer> _ignoreClanNpcIds;
private Map<DropListScope, List<IDropItem>> _dropLists;
private List<DropHolder> _dropListDeath;
private List<DropHolder> _dropListSpoil;
private double _collisionRadiusGrown;
private double _collisionHeightGrown;
private int _mpRewardValue;
@@ -556,49 +561,222 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
_ignoreClanNpcIds = ignoreClanNpcIds != null ? Collections.unmodifiableSet(ignoreClanNpcIds) : null;
}
public Map<DropListScope, List<IDropItem>> getDropLists()
public void addDrop(DropHolder dropHolder)
{
return _dropLists;
if (_dropListDeath == null)
{
_dropListDeath = new ArrayList<>();
}
_dropListDeath.add(dropHolder);
}
public void setDropLists(Map<DropListScope, List<IDropItem>> dropLists)
public void addSpoil(DropHolder dropHolder)
{
_dropLists = dropLists != null ? Collections.unmodifiableMap(dropLists) : null;
if (_dropListSpoil == null)
{
_dropListSpoil = new ArrayList<>();
}
_dropListSpoil.add(dropHolder);
}
public List<IDropItem> getDropList(DropListScope dropListScope)
public List<DropHolder> getDropList(DropType dropType)
{
return _dropLists != null ? _dropLists.get(dropListScope) : null;
switch (dropType)
{
case DROP:
case LUCKY_DROP: // never happens
{
return _dropListDeath;
}
case SPOIL:
{
return _dropListSpoil;
}
}
return null;
}
public Collection<ItemHolder> calculateDrops(DropListScope dropListScope, L2Character victim, L2Character killer)
public Collection<ItemHolder> calculateDrops(DropType dropType, L2Character victim, L2Character killer)
{
final List<IDropItem> dropList = getDropList(dropListScope);
final List<DropHolder> dropList = getDropList(dropType);
if (dropList == null)
{
return null;
}
final int levelDifference = victim.getLevel() - killer.getLevel();
Collection<ItemHolder> calculatedDrops = null;
for (IDropItem dropItem : dropList)
for (DropHolder dropItem : dropList)
{
final Collection<ItemHolder> drops = dropItem.calculateDrops(victim, killer);
if ((drops == null) || drops.isEmpty())
// check level gap that may prevent drop this item
final double levelGapChanceToDrop;
if (dropItem.getItemId() == Inventory.ADENA_ID)
{
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ADENA_MAX_LEVEL_DIFFERENCE, -Config.DROP_ADENA_MIN_LEVEL_DIFFERENCE, Config.DROP_ADENA_MIN_LEVEL_GAP_CHANCE, 100.0);
}
else
{
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ITEM_MAX_LEVEL_DIFFERENCE, -Config.DROP_ITEM_MIN_LEVEL_DIFFERENCE, Config.DROP_ITEM_MIN_LEVEL_GAP_CHANCE, 100.0);
}
if ((Rnd.nextDouble() * 100) > levelGapChanceToDrop)
{
continue;
}
if (calculatedDrops == null)
// calculate chances
final ItemHolder drop = calculateDrop(dropItem, victim, killer);
if (drop == null)
{
calculatedDrops = new LinkedList<>();
continue;
}
calculatedDrops.addAll(drops);
// create list
if (calculatedDrops == null)
{
calculatedDrops = new ArrayList<>();
}
// finally
calculatedDrops.add(drop);
}
return calculatedDrops;
}
/**
* All item drop chance calculations are done by this method.
* @param dropItem
* @param victim
* @param killer
* @return ItemHolder
*/
private ItemHolder calculateDrop(DropHolder dropItem, L2Character victim, L2Character killer)
{
switch (dropItem.getDropType())
{
case DROP:
case LUCKY_DROP:
{
final L2Item item = ItemTable.getInstance().getTemplate(dropItem.getItemId());
// chance
double rateChance = 1;
if (Config.RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId()) != null)
{
rateChance *= Config.RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId());
}
else if (item.hasExImmediateEffect())
{
rateChance *= Config.RATE_HERB_DROP_CHANCE_MULTIPLIER;
}
else if (victim.isRaid())
{
rateChance *= Config.RATE_RAID_DROP_CHANCE_MULTIPLIER;
}
else
{
rateChance *= Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
}
// premium chance
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
{
if (Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId()) != null)
{
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId());
}
else if (item.hasExImmediateEffect())
{
// TODO: Premium herb chance? :)
}
else if (victim.isRaid())
{
// TODO: Premium raid chance? :)
}
else
{
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE;
}
}
// calculate if item will drop
if ((Rnd.nextDouble() * 100) < (dropItem.getChance() * rateChance))
{
// amount is calculated after chance returned success
double rateAmount = 1;
if (Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
{
rateAmount *= Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId());
}
else if (item.hasExImmediateEffect())
{
rateAmount *= Config.RATE_HERB_DROP_AMOUNT_MULTIPLIER;
}
else if (victim.isRaid())
{
rateAmount *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
}
else
{
rateAmount *= Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
}
// premium chance
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
{
if (Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
{
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId());
}
else if (item.hasExImmediateEffect())
{
// TODO: Premium herb amount? :)
}
else if (victim.isRaid())
{
// TODO: Premium raid amount? :)
}
else
{
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT;
}
}
// finally
return new ItemHolder(dropItem.getItemId(), (long) (Rnd.get(dropItem.getMin(), dropItem.getMax()) * rateAmount));
}
break;
}
case SPOIL:
{
// chance
double rateChance = Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
// premium chance
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
{
rateChance *= Config.PREMIUM_RATE_SPOIL_CHANCE;
}
// calculate if item will be rewarded
if ((Rnd.nextDouble() * 100) < (dropItem.getChance() * rateChance))
{
// amount is calculated after chance returned success
double rateAmount = Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
// premium amount
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
{
rateAmount *= Config.PREMIUM_RATE_SPOIL_AMOUNT;
}
// finally
return new ItemHolder(dropItem.getItemId(), (long) (Rnd.get(dropItem.getMin(), dropItem.getMax()) * rateAmount));
}
break;
}
}
return null;
}
public double getCollisionRadiusGrown()
{
return _collisionRadiusGrown;

View File

@@ -1,56 +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 com.l2jmobius.gameserver.model.drops;
import com.l2jmobius.Config;
/**
* @author NosBit
*/
public class CorpseDropItem extends GeneralDropItem
{
/**
* @param itemId the item id
* @param min the min count
* @param max the max count
* @param chance the chance of this drop item
*/
public CorpseDropItem(int itemId, long min, long max, double chance)
{
super(itemId, min, max, chance);
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.drops.GeneralDropItem#getGlobalAmountMultiplier()
*/
@Override
protected double getGlobalAmountMultiplier(boolean isPremium)
{
return isPremium ? Config.PREMIUM_RATE_SPOIL_AMOUNT * Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER : Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER;
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.drops.GeneralDropItem#getGlobalChanceMultiplier()
*/
@Override
protected double getGlobalChanceMultiplier(boolean isPremium)
{
return isPremium ? Config.PREMIUM_RATE_SPOIL_CHANCE * Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER : Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
}
}

View File

@@ -1,56 +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 com.l2jmobius.gameserver.model.drops;
import com.l2jmobius.Config;
/**
* @author NosBit
*/
public class DeathDropItem extends GeneralDropItem
{
/**
* @param itemId the item id
* @param min the min count
* @param max the max count
* @param chance the chance of this drop item
*/
public DeathDropItem(int itemId, long min, long max, double chance)
{
super(itemId, min, max, chance);
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.drops.GeneralDropItem#getGlobalAmountMultiplier()
*/
@Override
protected double getGlobalAmountMultiplier(boolean isPremium)
{
return isPremium ? Config.PREMIUM_RATE_DROP_AMOUNT * Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER : Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.drops.GeneralDropItem#getGlobalChanceMultiplier()
*/
@Override
protected double getGlobalChanceMultiplier(boolean isPremium)
{
return isPremium ? Config.PREMIUM_RATE_DROP_CHANCE * Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER : Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
}
}

View File

@@ -1,90 +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 com.l2jmobius.gameserver.model.drops;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author NosBit
*/
public enum DropListScope
{
DEATH(DeathDropItem.class, GroupedDeathDropItem.class),
CORPSE(CorpseDropItem.class, GroupedCorpseDropItem.class);
private static final Logger _log = Logger.getLogger(DropListScope.class.getName());
private final Class<? extends GeneralDropItem> _dropItemClass;
private final Class<? extends GroupedGeneralDropItem> _groupedDropItemClass;
private DropListScope(Class<? extends GeneralDropItem> dropItemClass, Class<? extends GroupedGeneralDropItem> groupedDropItemClass)
{
_dropItemClass = dropItemClass;
_groupedDropItemClass = groupedDropItemClass;
}
public IDropItem newDropItem(int itemId, long min, long max, double chance)
{
final Constructor<? extends GeneralDropItem> constructor;
try
{
constructor = _dropItemClass.getConstructor(int.class, long.class, long.class, double.class);
}
catch (NoSuchMethodException | SecurityException e)
{
_log.log(Level.SEVERE, "Constructor(int, long, long, double) not found for " + _dropItemClass.getSimpleName(), e);
return null;
}
try
{
return constructor.newInstance(itemId, min, max, chance);
}
catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
_log.log(Level.SEVERE, "", e);
return null;
}
}
public GroupedGeneralDropItem newGroupedDropItem(double chance)
{
final Constructor<? extends GroupedGeneralDropItem> constructor;
try
{
constructor = _groupedDropItemClass.getConstructor(double.class);
}
catch (NoSuchMethodException | SecurityException e)
{
_log.log(Level.SEVERE, "Constructor(double) not found for " + _groupedDropItemClass.getSimpleName(), e);
return null;
}
try
{
return constructor.newInstance(chance);
}
catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
_log.log(Level.SEVERE, "", e);
return null;
}
}
}

View File

@@ -1,287 +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 com.l2jmobius.gameserver.model.drops;
import java.util.ArrayList;
import java.util.Collection;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.util.Util;
/**
* @author NosBit
*/
public class GeneralDropItem implements IDropItem
{
private final int _itemId;
private final long _min;
private final long _max;
private final double _chance;
/**
* @param itemId the item id
* @param min the min count
* @param max the max count
* @param chance the chance of this drop item
*/
public GeneralDropItem(int itemId, long min, long max, double chance)
{
_itemId = itemId;
_min = min;
_max = max;
_chance = chance;
}
protected double getGlobalChanceMultiplier(boolean isPremium)
{
return 1.;
}
protected double getGlobalAmountMultiplier(boolean isPremium)
{
return 1.;
}
private final long getMinMax(L2Character victim, L2Character killer, long val)
{
double multiplier = 1;
// individual drop amount
Float individualDropAmountMultiplier = null;
if (killer.getActingPlayer().hasPremiumStatus())
{
final Float normalMultiplier = Config.RATE_DROP_AMOUNT_BY_ID.get(getItemId());
final Float premiumMultiplier = Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(getItemId());
if ((normalMultiplier != null) && (premiumMultiplier != null))
{
individualDropAmountMultiplier = normalMultiplier * premiumMultiplier;
}
else if (normalMultiplier != null)
{
individualDropAmountMultiplier = normalMultiplier;
}
else if (premiumMultiplier != null)
{
individualDropAmountMultiplier = premiumMultiplier;
}
}
else
{
individualDropAmountMultiplier = Config.RATE_DROP_AMOUNT_BY_ID.get(getItemId());
}
if (individualDropAmountMultiplier != null)
{
// individual amount list multiplier
multiplier *= individualDropAmountMultiplier;
}
else
{
final L2Item item = ItemTable.getInstance().getTemplate(getItemId());
// global amount multiplier
if ((item != null) && item.hasExImmediateEffect())
{
// global herb amount multiplier
multiplier *= Config.RATE_HERB_DROP_AMOUNT_MULTIPLIER;
}
else if (victim.isRaid())
{
// global raid amount multiplier
multiplier *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
}
else
{
// drop type specific amount multiplier
multiplier *= getGlobalAmountMultiplier(killer.getActingPlayer().hasPremiumStatus());
}
}
// global champions amount multiplier
if (victim.isChampion())
{
multiplier *= getItemId() != Inventory.ADENA_ID ? Config.CHAMPION_REWARDS_AMOUNT : Config.CHAMPION_ADENAS_REWARDS_AMOUNT;
}
return (long) (val * multiplier);
}
/**
* Gets the item id
* @return the item id
*/
public int getItemId()
{
return _itemId;
}
/**
* Gets the min drop count
* @return the min
*/
public long getMin()
{
return _min;
}
/**
* Gets the min drop count
* @param victim the victim
* @param killer the killer
* @return the min modified by any rates.
*/
public long getMin(L2Character victim, L2Character killer)
{
return getMinMax(victim, killer, getMin());
}
/**
* Gets the max drop count
* @return the max
*/
public long getMax()
{
return _max;
}
/**
* Gets the max drop count
* @param victim the victim
* @param killer the killer
* @return the max modified by any rates.
*/
public long getMax(L2Character victim, L2Character killer)
{
return getMinMax(victim, killer, getMax());
}
/**
* Gets the chance of this drop item.
* @return the chance
*/
public double getChance()
{
return _chance;
}
/**
* Gets the chance of this drop item.
* @param victim the victim
* @param killer the killer
* @return the chance modified by any rates.
*/
public double getChance(L2Character victim, L2Character killer)
{
double multiplier = 1;
// individual drop chance
Float individualDropChanceMultiplier = null;
if (killer.getActingPlayer().hasPremiumStatus())
{
final Float normalMultiplier = Config.RATE_DROP_CHANCE_BY_ID.get(getItemId());
final Float premiumMultiplier = Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(getItemId());
if ((normalMultiplier != null) && (premiumMultiplier != null))
{
individualDropChanceMultiplier = normalMultiplier * premiumMultiplier;
}
else if (normalMultiplier != null)
{
individualDropChanceMultiplier = normalMultiplier;
}
else if (premiumMultiplier != null)
{
individualDropChanceMultiplier = premiumMultiplier;
}
}
else
{
individualDropChanceMultiplier = Config.RATE_DROP_CHANCE_BY_ID.get(getItemId());
}
if (individualDropChanceMultiplier != null)
{
multiplier *= individualDropChanceMultiplier;
}
else
{
final L2Item item = ItemTable.getInstance().getTemplate(getItemId());
if ((item != null) && item.hasExImmediateEffect())
{
multiplier *= Config.RATE_HERB_DROP_CHANCE_MULTIPLIER;
}
else if (victim.isRaid())
{
// global raid chance multiplier
multiplier *= Config.RATE_RAID_DROP_CHANCE_MULTIPLIER;
}
else
{
multiplier *= getGlobalChanceMultiplier(killer.getActingPlayer().hasPremiumStatus());
}
}
if (victim.isChampion())
{
multiplier *= getItemId() != Inventory.ADENA_ID ? Config.CHAMPION_REWARDS_CHANCE : Config.CHAMPION_ADENAS_REWARDS_CHANCE;
}
return (getChance() * multiplier);
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.drop.IDropItem#calculateDrops(com.l2jmobius.gameserver.model.actor.L2Character, com.l2jmobius.gameserver.model.actor.L2Character)
*/
@Override
public Collection<ItemHolder> calculateDrops(L2Character victim, L2Character killer)
{
final int levelDifference = victim.getLevel() - killer.getLevel();
final double levelGapChanceToDrop;
if (getItemId() == Inventory.ADENA_ID)
{
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ADENA_MAX_LEVEL_DIFFERENCE, -Config.DROP_ADENA_MIN_LEVEL_DIFFERENCE, Config.DROP_ADENA_MIN_LEVEL_GAP_CHANCE, 100.0);
}
else
{
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ITEM_MAX_LEVEL_DIFFERENCE, -Config.DROP_ITEM_MIN_LEVEL_DIFFERENCE, Config.DROP_ITEM_MIN_LEVEL_GAP_CHANCE, 100.0);
}
// There is a chance of level gap that it wont drop this item
if (levelGapChanceToDrop < (Rnd.nextDouble() * 100))
{
return null;
}
final double chance = getChance(victim, killer);
final boolean successes = chance > (Rnd.nextDouble() * 100);
if (successes)
{
final Collection<ItemHolder> items = new ArrayList<>(1);
final long baseDropCount = Rnd.get(getMin(victim, killer), getMax(victim, killer));
final long finaldropCount = (long) (Config.OLD_DROP_BEHAVIOR ? (baseDropCount * Math.max(1, chance / 100)) + (chance > 100 ? (chance % 100) > (Rnd.nextDouble() * 100) ? baseDropCount : 0 : 0) : baseDropCount);
items.add(new ItemHolder(getItemId(), finaldropCount));
return items;
}
return null;
}
}

View File

@@ -1,43 +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 com.l2jmobius.gameserver.model.drops;
import com.l2jmobius.Config;
/**
* @author NosBit
*/
public class GroupedCorpseDropItem extends GroupedGeneralDropItem
{
/**
* @param chance the chance of this drop item.
*/
public GroupedCorpseDropItem(double chance)
{
super(chance);
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem#getGlobalChanceMultiplier()
*/
@Override
protected double getGlobalChanceMultiplier()
{
return Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
}
}

View File

@@ -1,43 +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 com.l2jmobius.gameserver.model.drops;
import com.l2jmobius.Config;
/**
* @author NosBit
*/
public class GroupedDeathDropItem extends GroupedGeneralDropItem
{
/**
* @param chance the chance of this drop item.
*/
public GroupedDeathDropItem(double chance)
{
super(chance);
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem#getGlobalChanceMultiplier()
*/
@Override
protected double getGlobalChanceMultiplier()
{
return Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
}
}

View File

@@ -1,179 +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 com.l2jmobius.gameserver.model.drops;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2RaidBossInstance;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.util.Util;
/**
* @author NosBit
*/
public class GroupedGeneralDropItem implements IDropItem
{
private final double _chance;
private List<GeneralDropItem> _items;
/**
* @param chance the chance of this drop item.
*/
public GroupedGeneralDropItem(double chance)
{
_chance = chance;
}
protected double getGlobalChanceMultiplier()
{
return 1.;
}
/**
* Gets the chance of this drop item.
* @return the chance
*/
public double getChance()
{
return _chance;
}
/**
* Gets the chance of this drop item.
* @param victim the victim
* @param killer the killer
* @return the chance modified by any rates.
*/
public double getChance(L2Character victim, L2Character killer)
{
for (GeneralDropItem gdi : getItems())
{
final L2Item item = ItemTable.getInstance().getTemplate(gdi.getItemId());
if (item == null)
{
return 0;
}
if (!item.hasExImmediateEffect())
{
// individual chance
Float individualDropChanceMultiplier = null;
if (killer.getActingPlayer().hasPremiumStatus())
{
final Float normalMultiplier = Config.RATE_DROP_CHANCE_BY_ID.get(item.getId());
final Float premiumMultiplier = Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(item.getId());
if ((normalMultiplier != null) && (premiumMultiplier != null))
{
individualDropChanceMultiplier = normalMultiplier * premiumMultiplier;
}
else if (normalMultiplier != null)
{
individualDropChanceMultiplier = normalMultiplier;
}
else if (premiumMultiplier != null)
{
individualDropChanceMultiplier = premiumMultiplier;
}
}
else
{
individualDropChanceMultiplier = Config.RATE_DROP_CHANCE_BY_ID.get(item.getId());
}
if (individualDropChanceMultiplier != null)
{
return getChance() * individualDropChanceMultiplier;
}
return getChance() * getGlobalChanceMultiplier();
}
}
return getChance() * Config.RATE_HERB_DROP_CHANCE_MULTIPLIER;
}
/**
* Gets the items.
* @return the items
*/
public List<GeneralDropItem> getItems()
{
return _items;
}
/**
* Sets an item list to this drop item.
* @param items the item list
*/
public void setItems(List<GeneralDropItem> items)
{
_items = Collections.unmodifiableList(items);
}
/*
* (non-Javadoc)
* @see com.l2jmobius.gameserver.model.drop.IDropItem#calculateDrops(com.l2jmobius.gameserver.model.actor.L2Character, com.l2jmobius.gameserver.model.actor.L2Character)
*/
@Override
public Collection<ItemHolder> calculateDrops(L2Character victim, L2Character killer)
{
final int levelDifference = victim.getLevel() - killer.getLevel();
double chanceModifier;
if (victim instanceof L2RaidBossInstance)
{
chanceModifier = Math.max(0, Math.min(1, (levelDifference * 0.15) + 1));
}
else
{
chanceModifier = 1;
if (Util.map(levelDifference, -Config.DROP_ITEM_MAX_LEVEL_DIFFERENCE, -Config.DROP_ITEM_MIN_LEVEL_DIFFERENCE, Config.DROP_ITEM_MIN_LEVEL_GAP_CHANCE, 100.0) < (Rnd.nextDouble() * 100))
{
return null;
}
}
final double chance = getChance(victim, killer) * chanceModifier;
final boolean successes = chance > (Rnd.nextDouble() * 100);
if (successes)
{
double totalChance = 0;
final double random = (Rnd.nextDouble() * 100);
for (GeneralDropItem item : getItems())
{
// Grouped item chance rates should not be modified.
totalChance += item.getChance(victim, killer);
if (totalChance > random)
{
final Collection<ItemHolder> items = new ArrayList<>(1);
final long baseDropCount = Rnd.get(item.getMin(victim, killer), item.getMax(victim, killer));
final long finaldropCount = (long) (Config.OLD_DROP_BEHAVIOR ? (baseDropCount * Math.max(1, chance / 100)) + ((chance > 100) && ((chance % 100) > (Rnd.nextDouble() * 100)) ? baseDropCount : 0) : baseDropCount);
items.add(new ItemHolder(item.getItemId(), finaldropCount));
return items;
}
}
}
return null;
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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 com.l2jmobius.gameserver.model.holders;
import com.l2jmobius.gameserver.enums.DropType;
/**
* @author Mobius
*/
public class DropHolder
{
private final DropType _dropType;
private final int _itemId;
private final long _min;
private final long _max;
private final double _chance;
public DropHolder(DropType dropType, int itemId, long min, long max, double chance)
{
_dropType = dropType;
_itemId = itemId;
_min = min;
_max = max;
_chance = chance;
}
public DropType getDropType()
{
return _dropType;
}
public int getItemId()
{
return _itemId;
}
public long getMin()
{
return _min;
}
public long getMax()
{
return _max;
}
public double getChance()
{
return _chance;
}
}

View File

@@ -36,7 +36,7 @@ import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.instancemanager.EventShrineManager;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.announce.EventAnnouncement;
import com.l2jmobius.gameserver.model.drops.GeneralDropItem;
import com.l2jmobius.gameserver.model.holders.DropHolder;
import com.l2jmobius.gameserver.script.DateRange;
import com.l2jmobius.gameserver.util.Broadcast;
@@ -62,7 +62,7 @@ public class LongTimeEvent extends Quest
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
// Drop data for event
protected final List<GeneralDropItem> _dropList = new ArrayList<>();
protected final List<DropHolder> _dropList = new ArrayList<>();
protected class NpcSpawn
{
@@ -195,7 +195,7 @@ public class LongTimeEvent extends Quest
continue;
}
_dropList.add(new GeneralDropItem(itemId, minCount, maxCount, finalChance));
_dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance));
}
catch (NumberFormatException nfe)
{
@@ -272,7 +272,7 @@ public class LongTimeEvent extends Quest
// Add drop
if (_dropList != null)
{
for (GeneralDropItem drop : _dropList)
for (DropHolder drop : _dropList)
{
EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod);
}