Recipes rework.
Adapted from: L2jUnity free files.
This commit is contained in:
parent
6ccc5c8938
commit
7e1b0b4009
48107
L2J_Mobius_4.0_GrandCrusade/dist/game/data/Recipes.xml
vendored
48107
L2J_Mobius_4.0_GrandCrusade/dist/game/data/Recipes.xml
vendored
File diff suppressed because it is too large
Load Diff
@ -90,12 +90,16 @@ public final class EffectMasterHandler
|
||||
EffectHandler.getInstance().registerHandler("CpHealOverTime", CpHealOverTime::new);
|
||||
EffectHandler.getInstance().registerHandler("CpHealPercent", CpHealPercent::new);
|
||||
EffectHandler.getInstance().registerHandler("CpRegen", CpRegen::new);
|
||||
EffectHandler.getInstance().registerHandler("CraftingCritical", CraftingCritical::new);
|
||||
EffectHandler.getInstance().registerHandler("CreateCommonItem", CreateCommonItem::new);
|
||||
EffectHandler.getInstance().registerHandler("CreateItem", CreateItem::new);
|
||||
EffectHandler.getInstance().registerHandler("CreateItemRandom", CreateItemRandom::new);
|
||||
EffectHandler.getInstance().registerHandler("CriticalDamage", CriticalDamage::new);
|
||||
EffectHandler.getInstance().registerHandler("CriticalDamagePosition", CriticalDamagePosition::new);
|
||||
EffectHandler.getInstance().registerHandler("CriticalRate", CriticalRate::new);
|
||||
EffectHandler.getInstance().registerHandler("CriticalRatePositionBonus", CriticalRatePositionBonus::new);
|
||||
EffectHandler.getInstance().registerHandler("CrystalGradeModify", CrystalGradeModify::new);
|
||||
EffectHandler.getInstance().registerHandler("Crystallize", Crystallize::new);
|
||||
EffectHandler.getInstance().registerHandler("CubicMastery", CubicMastery::new);
|
||||
EffectHandler.getInstance().registerHandler("DamageBlock", DamageBlock::new);
|
||||
EffectHandler.getInstance().registerHandler("DamageShield", DamageShield::new);
|
||||
@ -265,6 +269,7 @@ public final class EffectMasterHandler
|
||||
EffectHandler.getInstance().registerHandler("ReflectSkill", ReflectSkill::new);
|
||||
EffectHandler.getInstance().registerHandler("RefuelAirship", RefuelAirship::new);
|
||||
EffectHandler.getInstance().registerHandler("Relax", Relax::new);
|
||||
EffectHandler.getInstance().registerHandler("RemoveEquipPenalty", RemoveEquipPenalty::new);
|
||||
EffectHandler.getInstance().registerHandler("ResetInstanceEntry", ResetInstanceEntry::new);
|
||||
EffectHandler.getInstance().registerHandler("ResistAbnormalByCategory", ResistAbnormalByCategory::new);
|
||||
EffectHandler.getInstance().registerHandler("ResistDDMagic", ResistDDMagic::new);
|
||||
|
@ -1,48 +1,31 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
|
||||
public class L2ManufactureItem
|
||||
{
|
||||
private final int _recipeId;
|
||||
private final long _cost;
|
||||
private final boolean _isDwarven;
|
||||
|
||||
public L2ManufactureItem(int recipeId, long cost)
|
||||
{
|
||||
_recipeId = recipeId;
|
||||
_cost = cost;
|
||||
_isDwarven = RecipeData.getInstance().getRecipeList(_recipeId).isDwarvenRecipe();
|
||||
}
|
||||
|
||||
public int getRecipeId()
|
||||
{
|
||||
return _recipeId;
|
||||
}
|
||||
|
||||
public long getCost()
|
||||
{
|
||||
return _cost;
|
||||
}
|
||||
|
||||
public boolean isDwarven()
|
||||
{
|
||||
return _isDwarven;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 handlers.effecthandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
|
||||
/**
|
||||
* @author Nik
|
||||
*/
|
||||
public class CraftingCritical extends AbstractStatAddEffect
|
||||
{
|
||||
public CraftingCritical(StatsSet params)
|
||||
{
|
||||
super(params, Stats.CRAFTING_CRITICAL);
|
||||
}
|
||||
}
|
64
L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateCommonItem.java
vendored
Normal file
64
L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateCommonItem.java
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 handlers.effecthandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* An effect that allows the player to create common recipe items up to a certain level.
|
||||
* @author Nik
|
||||
*/
|
||||
public final class CreateCommonItem extends AbstractEffect
|
||||
{
|
||||
private final int _recipeLevel;
|
||||
|
||||
public CreateCommonItem(StatsSet params)
|
||||
{
|
||||
_recipeLevel = params.getInt("value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStart(BuffInfo info)
|
||||
{
|
||||
return info.getEffected().isPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(L2Character effector, L2Character effected, Skill skill)
|
||||
{
|
||||
final L2PcInstance player = effected.getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
player.setCreateCommonItemLevel(_recipeLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(BuffInfo info)
|
||||
{
|
||||
final L2PcInstance player = info.getEffected().getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
player.setCreateCommonItemLevel(0);
|
||||
}
|
||||
}
|
||||
}
|
64
L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateItem.java
vendored
Normal file
64
L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateItem.java
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 handlers.effecthandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* An effect that allows the player to create dwarven recipe items up to a certain level.
|
||||
* @author Nik
|
||||
*/
|
||||
public final class CreateItem extends AbstractEffect
|
||||
{
|
||||
private final int _recipeLevel;
|
||||
|
||||
public CreateItem(StatsSet params)
|
||||
{
|
||||
_recipeLevel = params.getInt("value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStart(BuffInfo info)
|
||||
{
|
||||
return info.getEffected().isPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(L2Character effector, L2Character effected, Skill skill)
|
||||
{
|
||||
final L2PcInstance player = effected.getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
player.setCreateItemLevel(_recipeLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(BuffInfo info)
|
||||
{
|
||||
final L2PcInstance player = info.getEffected().getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
player.setCreateItemLevel(0);
|
||||
}
|
||||
}
|
||||
}
|
@ -29,11 +29,11 @@ import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
*/
|
||||
public final class CrystalGradeModify extends AbstractEffect
|
||||
{
|
||||
private final int _grade;
|
||||
private final int _amount;
|
||||
|
||||
public CrystalGradeModify(StatsSet params)
|
||||
{
|
||||
_grade = params.getInt("grade", 0);
|
||||
_amount = params.getInt("_amount", 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -45,7 +45,7 @@ public final class CrystalGradeModify extends AbstractEffect
|
||||
@Override
|
||||
public void onStart(L2Character effector, L2Character effected, Skill skill)
|
||||
{
|
||||
effected.getActingPlayer().setExpertisePenaltyBonus(_grade);
|
||||
effected.getActingPlayer().setExpertisePenaltyBonus(_amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
65
L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/Crystallize.java
vendored
Normal file
65
L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/Crystallize.java
vendored
Normal 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 handlers.effecthandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.ItemGrade;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* An effect that allows the player to crystallize items up to a certain grade.
|
||||
* @author Nik
|
||||
*/
|
||||
public final class Crystallize extends AbstractEffect
|
||||
{
|
||||
private final ItemGrade _grade;
|
||||
|
||||
public Crystallize(StatsSet params)
|
||||
{
|
||||
_grade = params.getEnum("grade", ItemGrade.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStart(BuffInfo info)
|
||||
{
|
||||
return info.getEffected().isPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(L2Character effector, L2Character effected, Skill skill)
|
||||
{
|
||||
final L2PcInstance player = effected.getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
player.setCrystallizeGrade(_grade);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(BuffInfo info)
|
||||
{
|
||||
final L2PcInstance player = info.getEffected().getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
player.setCrystallizeGrade(null);
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
package handlers.effecthandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.RecipeController;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
@ -25,6 +24,7 @@ import com.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList;
|
||||
|
||||
/**
|
||||
* Open Common Recipe Book effect implementation.
|
||||
@ -45,18 +45,24 @@ public final class OpenCommonRecipeBook extends AbstractEffect
|
||||
@Override
|
||||
public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item)
|
||||
{
|
||||
if (!effector.isPlayer())
|
||||
final L2PcInstance casterPlayer = effector.getActingPlayer();
|
||||
if (casterPlayer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance player = effector.getActingPlayer();
|
||||
if (player.getPrivateStoreType() != PrivateStoreType.NONE)
|
||||
if (casterPlayer.getPrivateStoreType() == PrivateStoreType.MANUFACTURE)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE);
|
||||
casterPlayer.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING);
|
||||
return;
|
||||
}
|
||||
|
||||
RecipeController.getInstance().requestBookOpen(player, false);
|
||||
if (casterPlayer.isProcessingTransaction())
|
||||
{
|
||||
casterPlayer.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE);
|
||||
return;
|
||||
}
|
||||
|
||||
casterPlayer.sendPacket(new RecipeBookItemList(casterPlayer, false));
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
package handlers.effecthandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.RecipeController;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
@ -25,6 +24,7 @@ import com.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList;
|
||||
|
||||
/**
|
||||
* Open Dwarf Recipe Book effect implementation.
|
||||
@ -45,18 +45,24 @@ public final class OpenDwarfRecipeBook extends AbstractEffect
|
||||
@Override
|
||||
public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item)
|
||||
{
|
||||
if (!effector.isPlayer())
|
||||
final L2PcInstance casterPlayer = effector.getActingPlayer();
|
||||
if (casterPlayer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance player = effector.getActingPlayer();
|
||||
if (player.getPrivateStoreType() != PrivateStoreType.NONE)
|
||||
if (casterPlayer.getPrivateStoreType() == PrivateStoreType.MANUFACTURE)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE);
|
||||
casterPlayer.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING);
|
||||
return;
|
||||
}
|
||||
|
||||
RecipeController.getInstance().requestBookOpen(player, true);
|
||||
if (casterPlayer.isProcessingTransaction())
|
||||
{
|
||||
casterPlayer.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE);
|
||||
return;
|
||||
}
|
||||
|
||||
casterPlayer.sendPacket(new RecipeBookItemList(casterPlayer, true));
|
||||
}
|
||||
}
|
||||
|
@ -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 handlers.effecthandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||
import com.l2jmobius.gameserver.model.items.type.CrystalType;
|
||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* An effect that removes equipment grade penalty. Its the base effect for the grade penalty mechanics.
|
||||
* @author Nik
|
||||
*/
|
||||
public final class RemoveEquipPenalty extends AbstractEffect
|
||||
{
|
||||
private final CrystalType _grade;
|
||||
|
||||
public RemoveEquipPenalty(StatsSet params)
|
||||
{
|
||||
_grade = params.getEnum("grade", CrystalType.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canStart(BuffInfo info)
|
||||
{
|
||||
return info.getEffected().isPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(L2Character effector, L2Character effected, Skill skill)
|
||||
{
|
||||
final L2PcInstance player = effected.getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
player.setExpertiseLevel(_grade);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit(BuffInfo info)
|
||||
{
|
||||
final L2PcInstance player = info.getEffected().getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
player.setExpertiseLevel(null);
|
||||
}
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ public class CharmOfCourage implements IItemHandler
|
||||
final L2PcInstance activeChar = playable.getActingPlayer();
|
||||
|
||||
int level = activeChar.getLevel();
|
||||
final int itemLevel = item.getItem().getCrystalType().getId();
|
||||
final int itemLevel = item.getItem().getCrystalType().getLevel();
|
||||
|
||||
if (level < 20)
|
||||
{
|
||||
|
@ -18,9 +18,9 @@ package handlers.itemhandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.handler.IItemHandler;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeList;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Playable;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
@ -40,15 +40,16 @@ public class Recipes implements IItemHandler
|
||||
}
|
||||
|
||||
final L2PcInstance activeChar = playable.getActingPlayer();
|
||||
if (activeChar.isInCraftMode())
|
||||
if (activeChar.isCrafting())
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING);
|
||||
return false;
|
||||
}
|
||||
|
||||
final L2RecipeList rp = RecipeData.getInstance().getRecipeByItemId(item.getId());
|
||||
final RecipeHolder rp = RecipeData.getInstance().getRecipeByRecipeItemId(item.getId());
|
||||
if (rp == null)
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -63,15 +64,15 @@ public class Recipes implements IItemHandler
|
||||
boolean recipeLimit = false;
|
||||
if (rp.isDwarvenRecipe())
|
||||
{
|
||||
canCraft = activeChar.hasDwarvenCraft();
|
||||
recipeLevel = (rp.getLevel() > activeChar.getDwarvenCraft());
|
||||
recipeLimit = (activeChar.getDwarvenRecipeBook().length >= activeChar.getDwarfRecipeLimit());
|
||||
canCraft = activeChar.getCreateItemLevel() > 0;
|
||||
recipeLevel = (rp.getLevel() > activeChar.getCreateItemLevel());
|
||||
recipeLimit = (activeChar.getDwarvenRecipeBook().size() >= activeChar.getDwarfRecipeLimit());
|
||||
}
|
||||
else
|
||||
{
|
||||
canCraft = activeChar.hasCommonCraft();
|
||||
recipeLevel = (rp.getLevel() > activeChar.getCommonCraft());
|
||||
recipeLimit = (activeChar.getCommonRecipeBook().length >= activeChar.getCommonRecipeLimit());
|
||||
canCraft = activeChar.getCreateCommonItemLevel() > 0;
|
||||
recipeLevel = (rp.getLevel() > activeChar.getCreateCommonItemLevel());
|
||||
recipeLimit = (activeChar.getCommonRecipeBook().size() >= activeChar.getCommonRecipeLimit());
|
||||
}
|
||||
|
||||
if (!canCraft)
|
||||
|
@ -119,7 +119,7 @@ public final class SocialAction implements IPlayerActionHandler
|
||||
}
|
||||
|
||||
SystemMessage sm;
|
||||
if (player.isInStoreMode() || player.isInCraftMode())
|
||||
if (player.isInStoreMode() || player.isCrafting())
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_PRIVATE_STORE_MODE_OR_IN_A_BATTLE_AND_CANNOT_BE_REQUESTED_FOR_A_COUPLE_ACTION);
|
||||
sm.addPcName(player);
|
||||
@ -198,7 +198,7 @@ public final class SocialAction implements IPlayerActionHandler
|
||||
|
||||
// Checks for partner.
|
||||
final L2PcInstance partner = target.getActingPlayer();
|
||||
if (partner.isInStoreMode() || partner.isInCraftMode())
|
||||
if (partner.isInStoreMode() || partner.isCrafting())
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_PRIVATE_STORE_MODE_OR_IN_A_BATTLE_AND_CANNOT_BE_REQUESTED_FOR_A_COUPLE_ACTION);
|
||||
sm.addPcName(partner);
|
||||
|
@ -2727,6 +2727,27 @@
|
||||
</magicLvl>
|
||||
<operateType>P</operateType>
|
||||
<magicCriticalRate>5</magicCriticalRate>
|
||||
<effects>
|
||||
<effect name="CreateItem">
|
||||
<value>
|
||||
<value level="1">1</value>
|
||||
<value level="2">2</value>
|
||||
<value level="3">3</value>
|
||||
<value level="4">4</value>
|
||||
<value level="5">5</value>
|
||||
<value level="6">6</value>
|
||||
<value level="7">7</value>
|
||||
<value level="8">8</value>
|
||||
<value level="9">9</value>
|
||||
<value level="10">10</value>
|
||||
<value level="11">11</value>
|
||||
<value level="12">12</value>
|
||||
<value level="13">13</value>
|
||||
<value level="14">14</value>
|
||||
<value level="15">15</value>
|
||||
</value>
|
||||
</effect>
|
||||
</effects>
|
||||
</skill>
|
||||
<skill id="173" toLevel="2" name="Acrobatics">
|
||||
<!-- Confirmed CT2.5 -->
|
||||
|
@ -2434,6 +2434,22 @@
|
||||
</magicLvl>
|
||||
<operateType>P</operateType>
|
||||
<magicCriticalRate>5</magicCriticalRate>
|
||||
<effects>
|
||||
<effect name="RemoveEquipPenalty">
|
||||
<grade>
|
||||
<value level="1">D</value>
|
||||
<value level="2">C</value>
|
||||
<value level="3">B</value>
|
||||
<value level="4">A</value>
|
||||
<value level="5">S</value>
|
||||
<value level="6">S80</value>
|
||||
<value level="7">S80</value>
|
||||
<value level="8">R</value>
|
||||
<value level="9">R95</value>
|
||||
<value level="10">R99</value>
|
||||
</grade>
|
||||
</effect>
|
||||
</effects>
|
||||
</skill>
|
||||
<skill id="244" toLevel="3" name="Armor Mastery">
|
||||
<!-- Confirmed CT2.5 -->
|
||||
@ -2615,6 +2631,18 @@
|
||||
</magicLvl>
|
||||
<operateType>P</operateType>
|
||||
<magicCriticalRate>5</magicCriticalRate>
|
||||
<effects>
|
||||
<effect name="Crystallize">
|
||||
<grade>
|
||||
<value level="1">D</value>
|
||||
<value level="2">C</value>
|
||||
<value level="3">B</value>
|
||||
<value level="4">A</value>
|
||||
<value level="5">S</value>
|
||||
<value level="6">R</value>
|
||||
</grade>
|
||||
</effect>
|
||||
</effects>
|
||||
</skill>
|
||||
<skill id="249" toLevel="42" name="Weapon Mastery">
|
||||
<!-- Confirmed CT2.5 -->
|
||||
|
@ -666,6 +666,22 @@
|
||||
</magicLvl>
|
||||
<operateType>P</operateType>
|
||||
<magicCriticalRate>5</magicCriticalRate>
|
||||
<effects>
|
||||
<effect name="CreateCommonItem">
|
||||
<value>
|
||||
<value level="1">1</value>
|
||||
<value level="2">2</value>
|
||||
<value level="3">3</value>
|
||||
<value level="4">4</value>
|
||||
<value level="5">5</value>
|
||||
<value level="6">6</value>
|
||||
<value level="7">7</value>
|
||||
<value level="8">8</value>
|
||||
<value level="9">9</value>
|
||||
<value level="10">10</value>
|
||||
</value>
|
||||
</effect>
|
||||
</effects>
|
||||
</skill>
|
||||
<skill id="1321" toLevel="1" name="Dwarven Craft">
|
||||
<!-- Confirmed CT2.5 -->
|
||||
|
@ -509,10 +509,25 @@
|
||||
</effects>
|
||||
</skill>
|
||||
<skill id="10312" toLevel="4" name="Crafting Mastery">
|
||||
<!-- AUTO GENERATED SKILL -->
|
||||
<!-- There is a small chance that the item quantity will double upon crafting. Critical level 1. -->
|
||||
<icon>icon.skill10312</icon>
|
||||
<magicLvl>
|
||||
<value level="1">85</value>
|
||||
<value level="2">90</value>
|
||||
<value level="3">95</value>
|
||||
<value level="4">99</value>
|
||||
</magicLvl>
|
||||
<operateType>P</operateType>
|
||||
<effects>
|
||||
<effect name="CraftingCritical">
|
||||
<amount>
|
||||
<value level="1">2.4</value>
|
||||
<value level="2">3.8</value>
|
||||
<value level="3">4.2</value>
|
||||
<value level="4">5.4</value>
|
||||
</amount>
|
||||
</effect>
|
||||
</effects>
|
||||
</skill>
|
||||
<skill id="10313" toLevel="4" name="Infinite Rush">
|
||||
<!-- Rush toward the frontal enemies to inflict Shock for 9 sec. Requires a sword, blunt, spear, fist weapon, dual blunt, or dual sword. -->
|
||||
|
@ -1268,10 +1268,10 @@
|
||||
</passiveConditions>
|
||||
<effects>
|
||||
<effect name="CrystalGradeModify">
|
||||
<grade>
|
||||
<amount>
|
||||
<value level="1">3</value>
|
||||
<value level="2">5</value>
|
||||
</grade>
|
||||
</amount>
|
||||
</effect>
|
||||
</effects>
|
||||
</skill>
|
||||
|
@ -1320,13 +1320,13 @@
|
||||
</passiveConditions>
|
||||
<effects>
|
||||
<effect name="CrystalGradeModify">
|
||||
<grade>
|
||||
<amount>
|
||||
<value level="1">1</value>
|
||||
<value level="2">2</value>
|
||||
<value level="3">3</value>
|
||||
<value level="4">4</value>
|
||||
<value level="5">5</value>
|
||||
</grade>
|
||||
</amount>
|
||||
</effect>
|
||||
</effects>
|
||||
</skill>
|
||||
|
@ -59,12 +59,16 @@ CpHealOverTime: Increases current CP by a given amount over time.
|
||||
CpHealPercent: Increases current CP by a given percentage amount.
|
||||
Cp: Increases current CP by a static amount.
|
||||
CpRegen: CP Regeneration stat.
|
||||
CraftingCritical: Crafting critical stat.
|
||||
CreateCommonItem: Allows the player to create common recipe items up to a certain level.
|
||||
CreateItem: Allows the player to create dwarven recipe items up to a certain level.
|
||||
CreateItemRandom: Creates an item randomly from a given list. All extractable items with chances to get different items are using this effect.
|
||||
CriticalDamage: Critical Damage stat.
|
||||
CriticalDamagePosition: Critical Damage depending on position stat.
|
||||
CriticalRate: Critical Rate stat.
|
||||
CriticalRatePositionBonus: Critical Rate depending on position stat. Ignores the critical rate cap of 500.
|
||||
CrystalGradeModify: Sets your Expertise Grade level. With this effect you can make lv. 40 player (C Grade) to wear S grade.
|
||||
Crystallize: Allows the player to crystallize items up to a certain grade.
|
||||
CubicMastery: Max cubics stat.
|
||||
DamageBlock: Blocks Hp or Mp damage/heal.
|
||||
DamageShield: Reflect damage percentage stat.
|
||||
@ -233,6 +237,7 @@ ReflectMagic: Deflects magical damage back to the attacker.
|
||||
ReflectSkill: Deflects physical/magical debuffs back to the attacker.
|
||||
RefuelAirship: Increases Airship's fuel.
|
||||
Relax: Sits down and increases HP regeneration until full.
|
||||
RemoveEquipPenalty: Removes equipment grade penalty. Its the base effect for the grade penalty mechanics.
|
||||
ResetInstanceEntry: Resets instance re-entry time. (l2jmobius)
|
||||
ResistAbnormalByCategory: Buff/debuff resist stat.
|
||||
ResistDDMagic: Magic resist stat (magic attack 50% effective or 1 damage)
|
||||
|
@ -2,88 +2,68 @@
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="list">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="item" minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:sequence>
|
||||
<xs:element name="recipe" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="altStatChange" minOccurs="0" maxOccurs="1">
|
||||
<xs:sequence>
|
||||
<xs:element name="materials">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="name" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="GIM" />
|
||||
<xs:enumeration value="SP" />
|
||||
<xs:enumeration value="XP" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="value" type="xs:positiveInteger" use="required" />
|
||||
<xs:sequence>
|
||||
<xs:element name="item" maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="id" type="xs:int" />
|
||||
<xs:attribute name="count" type="xs:long" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="ingredient" minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:element name="product">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="count" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="id" type="xs:positiveInteger" use="required" />
|
||||
<xs:sequence>
|
||||
<xs:element name="item" maxOccurs="unbounded" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="id" type="xs:int" />
|
||||
<xs:attribute name="count" type="xs:long" />
|
||||
<xs:attribute name="chance" type="xs:double" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="production" minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="npcFee" maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="count" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="id" type="xs:positiveInteger" use="required" />
|
||||
<xs:sequence>
|
||||
<xs:element name="item" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="id" type="xs:int" />
|
||||
<xs:attribute name="count" type="xs:long" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="productionRare" minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="statUse">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="count" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="id" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="rarity" type="xs:positiveInteger" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="statUse" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="name" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="HP" />
|
||||
<xs:enumeration value="MP" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="value" type="xs:positiveInteger" use="required" />
|
||||
<xs:sequence>
|
||||
<xs:element name="stat">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="name" type="xs:string"></xs:attribute>
|
||||
<xs:attribute name="val" type="xs:double" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="craftLevel" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:integer">
|
||||
<xs:minInclusive value="1" />
|
||||
<xs:maxInclusive value="14" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="id" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="name" type="xs:normalizedString" use="required" />
|
||||
<xs:attribute name="recipeId" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="successRate" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:integer">
|
||||
<xs:enumeration value="10" />
|
||||
<xs:enumeration value="25" />
|
||||
<xs:enumeration value="60" />
|
||||
<xs:enumeration value="70" />
|
||||
<xs:enumeration value="95" />
|
||||
<xs:enumeration value="100" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="type" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="common" />
|
||||
<xs:enumeration value="dwarven" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="id" type="xs:int" use="required" />
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:attribute name="level" type="xs:int" use="required" />
|
||||
<xs:attribute name="itemId" type="xs:int" use="required" />
|
||||
<xs:attribute name="successRate" type="xs:double" use="required" />
|
||||
<xs:attribute name="isCommonRecipe" type="xs:string" use="required" />
|
||||
<xs:attribute name="maxOffering" type="xs:long" use="optional" />
|
||||
<xs:attribute name="maxOfferingBonus" type="xs:double" use="optional" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
|
@ -1197,6 +1197,21 @@
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="grade">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence minOccurs="0">
|
||||
<xs:element maxOccurs="unbounded" name="value">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="level" type="xs:unsignedByte" use="required" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="side" type="xs:string" />
|
||||
<xs:element name="PARALYZE">
|
||||
<xs:complexType mixed="true">
|
||||
@ -2037,21 +2052,6 @@
|
||||
<xs:element name="hp" type="xs:unsignedByte" />
|
||||
<xs:element name="mp" type="xs:unsignedByte" />
|
||||
<xs:element name="cp" type="xs:unsignedByte" />
|
||||
<xs:element name="grade">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence minOccurs="0">
|
||||
<xs:element maxOccurs="unbounded" name="value">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:unsignedByte">
|
||||
<xs:attribute name="level" type="xs:unsignedByte" use="required" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="xp" type="xs:unsignedInt" />
|
||||
<xs:element name="ACCURACY_COMBAT">
|
||||
<xs:complexType mixed="true">
|
||||
|
@ -1,785 +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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.enums.StatType;
|
||||
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
||||
import com.l2jmobius.gameserver.model.L2ManufactureItem;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeInstance;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeList;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeStatInstance;
|
||||
import com.l2jmobius.gameserver.model.TempItem;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.CommonSkill;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeItemMakeInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeShopItemInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SetupGauge;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
public class RecipeController
|
||||
{
|
||||
protected static final Map<Integer, RecipeItemMaker> _activeMakers = new ConcurrentHashMap<>();
|
||||
|
||||
protected RecipeController()
|
||||
{
|
||||
}
|
||||
|
||||
public void requestBookOpen(L2PcInstance player, boolean isDwarvenCraft)
|
||||
{
|
||||
// Check if player is trying to alter recipe book while engaged in manufacturing.
|
||||
if (!_activeMakers.containsKey(player.getObjectId()))
|
||||
{
|
||||
final RecipeBookItemList response = new RecipeBookItemList(isDwarvenCraft, player.getMaxMp());
|
||||
response.addRecipes(isDwarvenCraft ? player.getDwarvenRecipeBook() : player.getCommonRecipeBook());
|
||||
player.sendPacket(response);
|
||||
return;
|
||||
}
|
||||
player.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING);
|
||||
}
|
||||
|
||||
public void requestMakeItemAbort(L2PcInstance player)
|
||||
{
|
||||
_activeMakers.remove(player.getObjectId()); // TODO: anything else here?
|
||||
}
|
||||
|
||||
public void requestManufactureItem(L2PcInstance manufacturer, int recipeListId, L2PcInstance player)
|
||||
{
|
||||
final L2RecipeList recipeList = RecipeData.getInstance().getValidRecipeList(player, recipeListId);
|
||||
if (recipeList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<L2RecipeList> dwarfRecipes = Arrays.asList(manufacturer.getDwarvenRecipeBook());
|
||||
final List<L2RecipeList> commonRecipes = Arrays.asList(manufacturer.getCommonRecipeBook());
|
||||
|
||||
if (!dwarfRecipes.contains(recipeList) && !commonRecipes.contains(recipeList))
|
||||
{
|
||||
Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " sent a false recipe id.", Config.DEFAULT_PUNISH);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if manufacturer is under manufacturing store or private store.
|
||||
if (Config.ALT_GAME_CREATION && _activeMakers.containsKey(manufacturer.getObjectId()))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.PLEASE_CLOSE_THE_SETUP_WINDOW_FOR_YOUR_PRIVATE_WORKSHOP_OR_PRIVATE_STORE_AND_TRY_AGAIN);
|
||||
return;
|
||||
}
|
||||
|
||||
final RecipeItemMaker maker = new RecipeItemMaker(manufacturer, recipeList, player);
|
||||
if (maker._isValid)
|
||||
{
|
||||
if (Config.ALT_GAME_CREATION)
|
||||
{
|
||||
_activeMakers.put(manufacturer.getObjectId(), maker);
|
||||
ThreadPoolManager.schedule(maker, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
maker.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void requestMakeItem(L2PcInstance player, int recipeListId)
|
||||
{
|
||||
// Check if player is trying to operate a private store or private workshop while engaged in combat.
|
||||
if (player.isInCombat() || player.isInDuel())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.WHILE_YOU_ARE_ENGAGED_IN_COMBAT_YOU_CANNOT_OPERATE_A_PRIVATE_STORE_OR_PRIVATE_WORKSHOP);
|
||||
return;
|
||||
}
|
||||
|
||||
final L2RecipeList recipeList = RecipeData.getInstance().getValidRecipeList(player, recipeListId);
|
||||
if (recipeList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<L2RecipeList> dwarfRecipes = Arrays.asList(player.getDwarvenRecipeBook());
|
||||
final List<L2RecipeList> commonRecipes = Arrays.asList(player.getCommonRecipeBook());
|
||||
|
||||
if (!dwarfRecipes.contains(recipeList) && !commonRecipes.contains(recipeList))
|
||||
{
|
||||
Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " sent a false recipe id.", Config.DEFAULT_PUNISH);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if player is busy (possible if alt game creation is enabled)
|
||||
if (Config.ALT_GAME_CREATION && _activeMakers.containsKey(player.getObjectId()))
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S2_S1);
|
||||
sm.addItemName(recipeList.getItemId());
|
||||
sm.addString("You are busy creating.");
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
final RecipeItemMaker maker = new RecipeItemMaker(player, recipeList, player);
|
||||
if (maker._isValid)
|
||||
{
|
||||
if (Config.ALT_GAME_CREATION)
|
||||
{
|
||||
_activeMakers.put(player.getObjectId(), maker);
|
||||
ThreadPoolManager.schedule(maker, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
maker.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class RecipeItemMaker implements Runnable
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(RecipeItemMaker.class.getName());
|
||||
protected boolean _isValid;
|
||||
protected List<TempItem> _items = null;
|
||||
protected final L2RecipeList _recipeList;
|
||||
protected final L2PcInstance _player; // "crafter"
|
||||
protected final L2PcInstance _target; // "customer"
|
||||
protected final Skill _skill;
|
||||
protected final int _skillId;
|
||||
protected final int _skillLevel;
|
||||
protected int _creationPasses = 1;
|
||||
protected int _itemGrab;
|
||||
protected int _exp = -1;
|
||||
protected int _sp = -1;
|
||||
protected long _price;
|
||||
protected int _totalItems;
|
||||
protected int _delay;
|
||||
|
||||
public RecipeItemMaker(L2PcInstance pPlayer, L2RecipeList pRecipeList, L2PcInstance pTarget)
|
||||
{
|
||||
_player = pPlayer;
|
||||
_target = pTarget;
|
||||
_recipeList = pRecipeList;
|
||||
|
||||
_isValid = false;
|
||||
_skillId = _recipeList.isDwarvenRecipe() ? CommonSkill.CREATE_DWARVEN.getId() : CommonSkill.CREATE_COMMON.getId();
|
||||
_skillLevel = _player.getSkillLevel(_skillId);
|
||||
_skill = _player.getKnownSkill(_skillId);
|
||||
|
||||
_player.isInCraftMode(true);
|
||||
|
||||
if (_player.isAlikeDead())
|
||||
{
|
||||
_player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_target.isAlikeDead())
|
||||
{
|
||||
_target.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_target.isProcessingTransaction())
|
||||
{
|
||||
_target.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_player.isProcessingTransaction())
|
||||
{
|
||||
_player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
// validate recipe list
|
||||
if (_recipeList.getRecipes().length == 0)
|
||||
{
|
||||
_player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
// validate skill level
|
||||
if (_recipeList.getLevel() > _skillLevel)
|
||||
{
|
||||
_player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
// check that customer can afford to pay for creation services
|
||||
if (_player != _target)
|
||||
{
|
||||
final L2ManufactureItem item = _player.getManufactureItems().get(_recipeList.getId());
|
||||
if (item != null)
|
||||
{
|
||||
_price = item.getCost();
|
||||
if (_target.getAdena() < _price) // check price
|
||||
{
|
||||
_target.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make temporary items
|
||||
_items = listItems(false);
|
||||
if (_items == null)
|
||||
{
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
for (TempItem i : _items)
|
||||
{
|
||||
_totalItems += i.getQuantity();
|
||||
}
|
||||
|
||||
// initial statUse checks
|
||||
if (!calculateStatUse(false, false))
|
||||
{
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
// initial AltStatChange checks
|
||||
if (Config.ALT_GAME_CREATION)
|
||||
{
|
||||
calculateAltStatChange();
|
||||
}
|
||||
|
||||
updateMakeInfo(true);
|
||||
updateCurMp();
|
||||
updateCurLoad();
|
||||
|
||||
_player.isInCraftMode(false);
|
||||
_isValid = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (!Config.IS_CRAFTING_ENABLED)
|
||||
{
|
||||
_target.sendMessage("Item creation is currently disabled.");
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((_player == null) || (_target == null))
|
||||
{
|
||||
LOGGER.warning("player or target == null (disconnected?), aborting" + _target + _player);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_player.isOnline() || !_target.isOnline())
|
||||
{
|
||||
LOGGER.warning("player or target is not online, aborting " + _target + _player);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.ALT_GAME_CREATION && !_activeMakers.containsKey(_player.getObjectId()))
|
||||
{
|
||||
if (_target != _player)
|
||||
{
|
||||
_target.sendMessage("Manufacture aborted");
|
||||
_player.sendMessage("Manufacture aborted");
|
||||
}
|
||||
else
|
||||
{
|
||||
_player.sendMessage("Item creation aborted");
|
||||
}
|
||||
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.ALT_GAME_CREATION && !_items.isEmpty())
|
||||
{
|
||||
|
||||
if (!calculateStatUse(true, true))
|
||||
{
|
||||
return; // check stat use
|
||||
}
|
||||
updateCurMp(); // update craft window mp bar
|
||||
|
||||
grabSomeItems(); // grab (equip) some more items with a nice msg to player
|
||||
|
||||
// if still not empty, schedule another pass
|
||||
if (!_items.isEmpty())
|
||||
{
|
||||
_delay = (int) (Config.ALT_GAME_CREATION_SPEED * _player.getStat().getReuseTime(_skill) * GameTimeController.TICKS_PER_SECOND * GameTimeController.MILLIS_IN_TICK);
|
||||
|
||||
// FIXME: please fix this packet to show crafting animation (somebody)
|
||||
final MagicSkillUse msk = new MagicSkillUse(_player, _skillId, _skillLevel, _delay, 0);
|
||||
_player.broadcastPacket(msk);
|
||||
|
||||
_player.sendPacket(new SetupGauge(_player.getObjectId(), 0, _delay));
|
||||
ThreadPoolManager.schedule(this, 100 + _delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
// for alt mode, sleep delay msec before finishing
|
||||
_player.sendPacket(new SetupGauge(_player.getObjectId(), 0, _delay));
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep(_delay);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
finishCrafting();
|
||||
}
|
||||
}
|
||||
} // for old craft mode just finish
|
||||
else
|
||||
{
|
||||
finishCrafting();
|
||||
}
|
||||
}
|
||||
|
||||
private void finishCrafting()
|
||||
{
|
||||
if (!Config.ALT_GAME_CREATION)
|
||||
{
|
||||
calculateStatUse(false, true);
|
||||
}
|
||||
|
||||
// first take adena for manufacture
|
||||
if ((_target != _player) && (_price > 0)) // customer must pay for services
|
||||
{
|
||||
// attempt to pay for item
|
||||
final L2ItemInstance adenatransfer = _target.transferItem("PayManufacture", _target.getInventory().getAdenaInstance().getObjectId(), _price, _player.getInventory(), _player);
|
||||
|
||||
if (adenatransfer == null)
|
||||
{
|
||||
_target.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_items = listItems(true); // this line actually takes materials from inventory
|
||||
if (_items == null)
|
||||
{
|
||||
// handle possible cheaters here
|
||||
// (they click craft then try to get rid of items in order to get free craft)
|
||||
}
|
||||
else if ((Rnd.get(100) < _recipeList.getSuccessRate()) || _target.tryLuck())
|
||||
{
|
||||
rewardPlayer(_target); // and immediately puts created item in its place
|
||||
updateMakeInfo(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_target != _player)
|
||||
{
|
||||
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_FAILED_TO_CREATE_S2_FOR_C1_AT_THE_PRICE_OF_S3_ADENA);
|
||||
msg.addString(_target.getName());
|
||||
msg.addItemName(_recipeList.getItemId());
|
||||
msg.addLong(_price);
|
||||
_player.sendPacket(msg);
|
||||
|
||||
msg = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_FAILED_TO_CREATE_S2_AT_THE_PRICE_OF_S3_ADENA);
|
||||
msg.addString(_player.getName());
|
||||
msg.addItemName(_recipeList.getItemId());
|
||||
msg.addLong(_price);
|
||||
_target.sendPacket(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
_target.sendPacket(SystemMessageId.YOU_FAILED_AT_MIXING_THE_ITEM);
|
||||
}
|
||||
updateMakeInfo(false);
|
||||
}
|
||||
// update load and mana bar of craft window
|
||||
updateCurMp();
|
||||
_activeMakers.remove(_player.getObjectId());
|
||||
_player.isInCraftMode(false);
|
||||
_target.sendItemList(false);
|
||||
}
|
||||
|
||||
private void updateMakeInfo(boolean success)
|
||||
{
|
||||
if (_target == _player)
|
||||
{
|
||||
_target.sendPacket(new RecipeItemMakeInfo(_recipeList.getId(), _target, success));
|
||||
}
|
||||
else
|
||||
{
|
||||
_target.sendPacket(new RecipeShopItemInfo(_player, _recipeList.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCurLoad()
|
||||
{
|
||||
_target.sendPacket(new ExUserInfoInvenWeight(_target));
|
||||
}
|
||||
|
||||
private void updateCurMp()
|
||||
{
|
||||
final StatusUpdate su = new StatusUpdate(_target);
|
||||
su.addUpdate(StatusUpdateType.CUR_MP, (int) _target.getCurrentMp());
|
||||
_target.sendPacket(su);
|
||||
}
|
||||
|
||||
private void grabSomeItems()
|
||||
{
|
||||
int grabItems = _itemGrab;
|
||||
while ((grabItems > 0) && !_items.isEmpty())
|
||||
{
|
||||
final TempItem item = _items.get(0);
|
||||
|
||||
int count = item.getQuantity();
|
||||
if (count >= grabItems)
|
||||
{
|
||||
count = grabItems;
|
||||
}
|
||||
|
||||
item.setQuantity(item.getQuantity() - count);
|
||||
if (item.getQuantity() <= 0)
|
||||
{
|
||||
_items.remove(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_items.set(0, item);
|
||||
}
|
||||
|
||||
grabItems -= count;
|
||||
|
||||
if (_target == _player)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.EQUIPPED_S1_S2); // you equipped ...
|
||||
sm.addLong(count);
|
||||
sm.addItemName(item.getItemId());
|
||||
_player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
_target.sendMessage("Manufacturer " + _player.getName() + " used " + count + " " + item.getItemName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AltStatChange parameters make their effect here
|
||||
private void calculateAltStatChange()
|
||||
{
|
||||
_itemGrab = _skillLevel;
|
||||
|
||||
for (L2RecipeStatInstance altStatChange : _recipeList.getAltStatChange())
|
||||
{
|
||||
if (altStatChange.getType() == StatType.XP)
|
||||
{
|
||||
_exp = altStatChange.getValue();
|
||||
}
|
||||
else if (altStatChange.getType() == StatType.SP)
|
||||
{
|
||||
_sp = altStatChange.getValue();
|
||||
}
|
||||
else if (altStatChange.getType() == StatType.GIM)
|
||||
{
|
||||
_itemGrab *= altStatChange.getValue();
|
||||
}
|
||||
}
|
||||
// determine number of creation passes needed
|
||||
_creationPasses = (_totalItems / _itemGrab) + ((_totalItems % _itemGrab) != 0 ? 1 : 0);
|
||||
if (_creationPasses < 1)
|
||||
{
|
||||
_creationPasses = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// StatUse
|
||||
private boolean calculateStatUse(boolean isWait, boolean isReduce)
|
||||
{
|
||||
boolean ret = true;
|
||||
for (L2RecipeStatInstance statUse : _recipeList.getStatUse())
|
||||
{
|
||||
final double modifiedValue = statUse.getValue() / _creationPasses;
|
||||
if (statUse.getType() == StatType.HP)
|
||||
{
|
||||
// we do not want to kill the player, so its CurrentHP must be greater than the reduce value
|
||||
if (_player.getCurrentHp() <= modifiedValue)
|
||||
{
|
||||
// rest (wait for HP)
|
||||
if (Config.ALT_GAME_CREATION && isWait)
|
||||
{
|
||||
_player.sendPacket(new SetupGauge(_player.getObjectId(), 0, _delay));
|
||||
ThreadPoolManager.schedule(this, 100 + _delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
_target.sendPacket(SystemMessageId.NOT_ENOUGH_HP);
|
||||
abort();
|
||||
}
|
||||
ret = false;
|
||||
}
|
||||
else if (isReduce)
|
||||
{
|
||||
_player.reduceCurrentHp(modifiedValue, _player, _skill);
|
||||
}
|
||||
}
|
||||
else if (statUse.getType() == StatType.MP)
|
||||
{
|
||||
if (_player.getCurrentMp() < modifiedValue)
|
||||
{
|
||||
// rest (wait for MP)
|
||||
if (Config.ALT_GAME_CREATION && isWait)
|
||||
{
|
||||
_player.sendPacket(new SetupGauge(_player.getObjectId(), 0, _delay));
|
||||
ThreadPoolManager.schedule(this, 100 + _delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
_target.sendPacket(SystemMessageId.NOT_ENOUGH_MP);
|
||||
abort();
|
||||
}
|
||||
ret = false;
|
||||
}
|
||||
else if (isReduce)
|
||||
{
|
||||
_player.reduceCurrentMp(modifiedValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is an unknown StatUse value
|
||||
_target.sendMessage("Recipe error!!!, please tell this to your GM.");
|
||||
ret = false;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<TempItem> listItems(boolean remove)
|
||||
{
|
||||
final L2RecipeInstance[] recipes = _recipeList.getRecipes();
|
||||
final Inventory inv = _target.getInventory();
|
||||
final List<TempItem> materials = new ArrayList<>();
|
||||
SystemMessage sm;
|
||||
|
||||
for (L2RecipeInstance recipe : recipes)
|
||||
{
|
||||
if (recipe.getQuantity() > 0)
|
||||
{
|
||||
final L2ItemInstance item = inv.getItemByItemId(recipe.getItemId());
|
||||
final long itemQuantityAmount = item == null ? 0 : item.getCount();
|
||||
|
||||
// check materials
|
||||
if (itemQuantityAmount < recipe.getQuantity())
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_MORE_S1_S);
|
||||
sm.addItemName(recipe.getItemId());
|
||||
sm.addLong(recipe.getQuantity() - itemQuantityAmount);
|
||||
_target.sendPacket(sm);
|
||||
|
||||
abort();
|
||||
return null;
|
||||
}
|
||||
|
||||
// make new temporary object, just for counting purposes
|
||||
materials.add(new TempItem(item, recipe.getQuantity()));
|
||||
}
|
||||
}
|
||||
|
||||
if (remove)
|
||||
{
|
||||
for (TempItem tmp : materials)
|
||||
{
|
||||
inv.destroyItemByItemId("Manufacture", tmp.getItemId(), tmp.getQuantity(), _target, _player);
|
||||
|
||||
if (tmp.getQuantity() > 1)
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.S2_S1_S_DISAPPEARED);
|
||||
sm.addItemName(tmp.getItemId());
|
||||
sm.addLong(tmp.getQuantity());
|
||||
_target.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.S1_DISAPPEARED);
|
||||
sm.addItemName(tmp.getItemId());
|
||||
_target.sendPacket(sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
return materials;
|
||||
}
|
||||
|
||||
private void abort()
|
||||
{
|
||||
updateMakeInfo(false);
|
||||
_player.isInCraftMode(false);
|
||||
_activeMakers.remove(_player.getObjectId());
|
||||
}
|
||||
|
||||
private void rewardPlayer(L2PcInstance player)
|
||||
{
|
||||
final int rareProdId = _recipeList.getRareItemId();
|
||||
int itemId = _recipeList.getItemId();
|
||||
int itemCount = _recipeList.getCount();
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(itemId);
|
||||
|
||||
// check that the current recipe has a rare production or not
|
||||
if ((rareProdId != -1) && ((rareProdId == itemId) || Config.CRAFT_MASTERWORK))
|
||||
{
|
||||
if (Rnd.get(100) < _recipeList.getRarity())
|
||||
{
|
||||
itemId = rareProdId;
|
||||
itemCount = _recipeList.getRareCount();
|
||||
}
|
||||
}
|
||||
|
||||
if (player.tryLuck())
|
||||
{
|
||||
itemCount *= 2;
|
||||
}
|
||||
|
||||
_target.getInventory().addItem("Manufacture", itemId, itemCount, _target, _player);
|
||||
|
||||
// inform customer of earned item
|
||||
SystemMessage sm = null;
|
||||
if (_target != _player)
|
||||
{
|
||||
// inform manufacturer of earned profit
|
||||
if (itemCount == 1)
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.S2_HAS_BEEN_CREATED_FOR_C1_AFTER_THE_PAYMENT_OF_S3_ADENA_WAS_RECEIVED);
|
||||
sm.addString(_target.getName());
|
||||
sm.addItemName(itemId);
|
||||
sm.addLong(_price);
|
||||
_player.sendPacket(sm);
|
||||
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_CREATED_S2_AFTER_RECEIVING_S3_ADENA);
|
||||
sm.addString(_player.getName());
|
||||
sm.addItemName(itemId);
|
||||
sm.addLong(_price);
|
||||
_target.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.S3_S2_S_HAVE_BEEN_CREATED_FOR_C1_AT_THE_PRICE_OF_S4_ADENA);
|
||||
sm.addString(_target.getName());
|
||||
sm.addInt(itemCount);
|
||||
sm.addItemName(itemId);
|
||||
sm.addLong(_price);
|
||||
_player.sendPacket(sm);
|
||||
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_CREATED_S3_S2_S_AT_THE_PRICE_OF_S4_ADENA);
|
||||
sm.addString(_player.getName());
|
||||
sm.addInt(itemCount);
|
||||
sm.addItemName(itemId);
|
||||
sm.addLong(_price);
|
||||
_target.sendPacket(sm);
|
||||
}
|
||||
}
|
||||
|
||||
if (itemCount > 1)
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(itemId);
|
||||
sm.addLong(itemCount);
|
||||
_target.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S1);
|
||||
sm.addItemName(itemId);
|
||||
_target.sendPacket(sm);
|
||||
}
|
||||
|
||||
if (Config.ALT_GAME_CREATION)
|
||||
{
|
||||
final int recipeLevel = _recipeList.getLevel();
|
||||
if (_exp < 0)
|
||||
{
|
||||
_exp = template.getReferencePrice() * itemCount;
|
||||
_exp /= recipeLevel;
|
||||
}
|
||||
if (_sp < 0)
|
||||
{
|
||||
_sp = _exp / 10;
|
||||
}
|
||||
if (itemId == rareProdId)
|
||||
{
|
||||
_exp *= Config.ALT_GAME_CREATION_RARE_XPSP_RATE;
|
||||
_sp *= Config.ALT_GAME_CREATION_RARE_XPSP_RATE;
|
||||
}
|
||||
|
||||
if (_exp < 0)
|
||||
{
|
||||
_exp = 0;
|
||||
}
|
||||
if (_sp < 0)
|
||||
{
|
||||
_sp = 0;
|
||||
}
|
||||
|
||||
for (int i = _skillLevel; i > recipeLevel; i--)
|
||||
{
|
||||
_exp /= 4;
|
||||
_sp /= 4;
|
||||
}
|
||||
|
||||
// Added multiplication of Creation speed with XP/SP gain slower crafting -> more XP,
|
||||
// faster crafting -> less XP you can use ALT_GAME_CREATION_XP_RATE/SP to modify XP/SP gained (default = 1)
|
||||
_player.addExpAndSp((int) _player.getStat().getValue(Stats.EXPSP_RATE, _exp * Config.ALT_GAME_CREATION_XP_RATE * Config.ALT_GAME_CREATION_SPEED), (int) _player.getStat().getValue(Stats.EXPSP_RATE, _sp * Config.ALT_GAME_CREATION_SP_RATE * Config.ALT_GAME_CREATION_SPEED));
|
||||
}
|
||||
updateMakeInfo(true); // success
|
||||
}
|
||||
}
|
||||
|
||||
public static RecipeController getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final RecipeController _instance = new RecipeController();
|
||||
}
|
||||
}
|
@ -21,6 +21,9 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -28,7 +31,6 @@ import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.LoginServerThread;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.L2ManufactureItem;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.TradeItem;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
@ -133,12 +135,12 @@ public class OfflineTradersTable
|
||||
continue;
|
||||
}
|
||||
title = pc.getStoreName();
|
||||
for (L2ManufactureItem i : pc.getManufactureItems().values())
|
||||
for (Entry<Integer, Long> entry : pc.getManufactureItems().entrySet())
|
||||
{
|
||||
stm_items.setInt(1, pc.getObjectId());
|
||||
stm_items.setInt(2, i.getRecipeId());
|
||||
stm_items.setInt(2, entry.getKey());
|
||||
stm_items.setLong(3, 0);
|
||||
stm_items.setLong(4, i.getCost());
|
||||
stm_items.setLong(4, entry.getValue());
|
||||
stm_items.executeUpdate();
|
||||
stm_items.clearParameters();
|
||||
}
|
||||
@ -274,10 +276,12 @@ public class OfflineTradersTable
|
||||
}
|
||||
case MANUFACTURE:
|
||||
{
|
||||
final Map<Integer, Long> manufactureItems = new HashMap<>();
|
||||
while (items.next())
|
||||
{
|
||||
player.getManufactureItems().put(items.getInt(2), new L2ManufactureItem(items.getInt(2), items.getLong(4)));
|
||||
manufactureItems.put(items.getInt(2), items.getLong(4));
|
||||
}
|
||||
player.setManufactureItems(manufactureItems);
|
||||
player.setStoreName(rs.getString("title"));
|
||||
break;
|
||||
}
|
||||
@ -407,12 +411,12 @@ public class OfflineTradersTable
|
||||
{
|
||||
title = trader.getStoreName();
|
||||
}
|
||||
for (L2ManufactureItem i : trader.getManufactureItems().values())
|
||||
for (Entry<Integer, Long> entry : trader.getManufactureItems().entrySet())
|
||||
{
|
||||
stm3.setInt(1, trader.getObjectId());
|
||||
stm3.setInt(2, i.getRecipeId());
|
||||
stm3.setInt(2, entry.getKey());
|
||||
stm3.setLong(3, 0);
|
||||
stm3.setLong(4, i.getCost());
|
||||
stm3.setLong(4, entry.getValue());
|
||||
stm3.executeUpdate();
|
||||
stm3.clearParameters();
|
||||
}
|
||||
|
@ -18,35 +18,33 @@ package com.l2jmobius.gameserver.data.xml.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeInstance;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeList;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeStatInstance;
|
||||
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
|
||||
/**
|
||||
* The Class RecipeData.
|
||||
* @author Zoey76
|
||||
* @author Nik
|
||||
*/
|
||||
public class RecipeData implements IGameXmlReader
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(RecipeData.class.getName());
|
||||
|
||||
private final Map<Integer, L2RecipeList> _recipes = new HashMap<>();
|
||||
private final Map<Integer, RecipeHolder> _recipes = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new recipe data.
|
||||
*/
|
||||
protected RecipeData()
|
||||
{
|
||||
load();
|
||||
@ -63,205 +61,108 @@ public class RecipeData implements IGameXmlReader
|
||||
@Override
|
||||
public void parseDocument(Document doc, File f)
|
||||
{
|
||||
// TODO: Cleanup checks enforced by XSD.
|
||||
final List<L2RecipeInstance> recipePartList = new ArrayList<>();
|
||||
final List<L2RecipeStatInstance> recipeStatUseList = new ArrayList<>();
|
||||
final List<L2RecipeStatInstance> recipeAltStatChangeList = new ArrayList<>();
|
||||
StatsSet set;
|
||||
Node att;
|
||||
NamedNodeMap attrs;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
RECIPES_FILE: for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(d.getNodeName()))
|
||||
if ("recipe".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
recipePartList.clear();
|
||||
recipeStatUseList.clear();
|
||||
recipeAltStatChangeList.clear();
|
||||
final NamedNodeMap attrs = d.getAttributes();
|
||||
Node att;
|
||||
int id = -1;
|
||||
boolean haveRare = false;
|
||||
final StatsSet set = new StatsSet();
|
||||
|
||||
att = attrs.getNamedItem("id");
|
||||
if (att == null)
|
||||
attrs = d.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing id for recipe item, skipping");
|
||||
continue;
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
id = Integer.parseInt(att.getNodeValue());
|
||||
set.set("id", id);
|
||||
|
||||
att = attrs.getNamedItem("recipeId");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing recipeId for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("recipeId", Integer.parseInt(att.getNodeValue()));
|
||||
|
||||
att = attrs.getNamedItem("name");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing name for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("recipeName", att.getNodeValue());
|
||||
|
||||
att = attrs.getNamedItem("craftLevel");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing level for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("craftLevel", Integer.parseInt(att.getNodeValue()));
|
||||
|
||||
att = attrs.getNamedItem("type");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing type for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("isDwarvenRecipe", att.getNodeValue().equalsIgnoreCase("dwarven"));
|
||||
|
||||
att = attrs.getNamedItem("successRate");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing successRate for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("successRate", Integer.parseInt(att.getNodeValue()));
|
||||
final int recipeId = set.getInt("id");
|
||||
List<ItemHolder> materials = Collections.emptyList();
|
||||
List<ItemChanceHolder> productGroup = Collections.emptyList();
|
||||
List<ItemHolder> npcFee = Collections.emptyList();
|
||||
final Map<StatusUpdateType, Double> statUse = new HashMap<>();
|
||||
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
if ("statUse".equalsIgnoreCase(c.getNodeName()))
|
||||
if ("materials".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
final String statName = c.getAttributes().getNamedItem("name").getNodeValue();
|
||||
final int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue());
|
||||
try
|
||||
{
|
||||
recipeStatUseList.add(new L2RecipeStatInstance(statName, value));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Error in StatUse parameter for recipe item id: " + id + ", skipping");
|
||||
continue RECIPES_FILE;
|
||||
}
|
||||
materials = getItemList(c);
|
||||
}
|
||||
else if ("altStatChange".equalsIgnoreCase(c.getNodeName()))
|
||||
else if ("product".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
final String statName = c.getAttributes().getNamedItem("name").getNodeValue();
|
||||
final int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue());
|
||||
try
|
||||
productGroup = getItemList(c).stream().map(ItemChanceHolder.class::cast).collect(Collectors.toList());
|
||||
}
|
||||
else if ("npcFee".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
npcFee = getItemList(c);
|
||||
}
|
||||
else if ("statUse".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
for (Node b = c.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
recipeAltStatChangeList.add(new L2RecipeStatInstance(statName, value));
|
||||
if ("stat".equalsIgnoreCase(b.getNodeName()))
|
||||
{
|
||||
StatusUpdateType stat = StatusUpdateType.valueOf(b.getAttributes().getNamedItem("name").getNodeValue());
|
||||
double value = Double.parseDouble(b.getAttributes().getNamedItem("val").getNodeValue());
|
||||
statUse.put(stat, value);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Error in AltStatChange parameter for recipe item id: " + id + ", skipping");
|
||||
continue RECIPES_FILE;
|
||||
}
|
||||
}
|
||||
else if ("ingredient".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
final int ingId = Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue());
|
||||
final int ingCount = Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue());
|
||||
recipePartList.add(new L2RecipeInstance(ingId, ingCount));
|
||||
}
|
||||
else if ("production".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
set.set("itemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()));
|
||||
set.set("count", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()));
|
||||
}
|
||||
else if ("productionRare".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
set.set("rareItemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()));
|
||||
set.set("rareCount", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()));
|
||||
set.set("rarity", Integer.parseInt(c.getAttributes().getNamedItem("rarity").getNodeValue()));
|
||||
haveRare = true;
|
||||
}
|
||||
}
|
||||
|
||||
final L2RecipeList recipeList = new L2RecipeList(set, haveRare);
|
||||
for (L2RecipeInstance recipePart : recipePartList)
|
||||
{
|
||||
recipeList.addRecipe(recipePart);
|
||||
}
|
||||
for (L2RecipeStatInstance recipeStatUse : recipeStatUseList)
|
||||
{
|
||||
recipeList.addStatUse(recipeStatUse);
|
||||
}
|
||||
for (L2RecipeStatInstance recipeAltStatChange : recipeAltStatChangeList)
|
||||
{
|
||||
recipeList.addAltStatChange(recipeAltStatChange);
|
||||
}
|
||||
|
||||
_recipes.put(id, recipeList);
|
||||
_recipes.put(recipeId, new RecipeHolder(set, materials, productGroup, npcFee, statUse));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recipe list.
|
||||
* @param listId the list id
|
||||
* @return the recipe list
|
||||
*/
|
||||
public L2RecipeList getRecipeList(int listId)
|
||||
private List<ItemHolder> getItemList(Node c)
|
||||
{
|
||||
return _recipes.get(listId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recipe by item id.
|
||||
* @param itemId the item id
|
||||
* @return the recipe by item id
|
||||
*/
|
||||
public L2RecipeList getRecipeByItemId(int itemId)
|
||||
{
|
||||
for (L2RecipeList find : _recipes.values())
|
||||
final List<ItemHolder> items = new ArrayList<>();
|
||||
for (Node b = c.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
if (find.getRecipeId() == itemId)
|
||||
if ("item".equalsIgnoreCase(b.getNodeName()))
|
||||
{
|
||||
return find;
|
||||
int itemId = Integer.parseInt(b.getAttributes().getNamedItem("id").getNodeValue());
|
||||
long itemCount = Long.parseLong(b.getAttributes().getNamedItem("count").getNodeValue());
|
||||
|
||||
if (b.getAttributes().getNamedItem("chance") != null)
|
||||
{
|
||||
double chance = Double.parseDouble(b.getAttributes().getNamedItem("chance").getNodeValue());
|
||||
items.add(new ItemChanceHolder(itemId, chance, itemCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
items.add(new ItemHolder(itemId, itemCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all item ids.
|
||||
* @return the all item ids
|
||||
* Gets the recipe by recipe item id.
|
||||
* @param itemId the recipe's item id
|
||||
* @return {@code RecipeHolder} for the given recipe item id {@code null} if there is no recipe data connected with this recipe item id.
|
||||
*/
|
||||
public int[] getAllItemIds()
|
||||
public RecipeHolder getRecipeByRecipeItemId(int itemId)
|
||||
{
|
||||
final int[] idList = new int[_recipes.size()];
|
||||
int i = 0;
|
||||
for (L2RecipeList rec : _recipes.values())
|
||||
{
|
||||
idList[i++] = rec.getRecipeId();
|
||||
}
|
||||
return idList;
|
||||
return _recipes.values().stream().filter(r -> r.getItemId() == itemId).findAny().orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the valid recipe list.
|
||||
* @param player the player
|
||||
* @param id the recipe list id
|
||||
* @return the valid recipe list
|
||||
* @param recipeId the id of the recipe, NOT the recipe item id.
|
||||
* @return {@code RecipeHolder} containing all the info necessary for crafting a recipe or {@code null} if there is no data for this recipeId.
|
||||
*/
|
||||
public L2RecipeList getValidRecipeList(L2PcInstance player, int id)
|
||||
public RecipeHolder getRecipe(int recipeId)
|
||||
{
|
||||
final L2RecipeList recipeList = _recipes.get(id);
|
||||
if ((recipeList == null) || (recipeList.getRecipes().length == 0))
|
||||
{
|
||||
player.sendMessage("No recipe for: " + id);
|
||||
player.isInCraftMode(false);
|
||||
return null;
|
||||
}
|
||||
return recipeList;
|
||||
return _recipes.get(recipeId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,6 @@ import com.l2jmobius.gameserver.model.conditions.ConditionPlayerCloakStatus;
|
||||
import com.l2jmobius.gameserver.model.conditions.ConditionPlayerCp;
|
||||
import com.l2jmobius.gameserver.model.conditions.ConditionPlayerDualclass;
|
||||
import com.l2jmobius.gameserver.model.conditions.ConditionPlayerFlyMounted;
|
||||
import com.l2jmobius.gameserver.model.conditions.ConditionPlayerGrade;
|
||||
import com.l2jmobius.gameserver.model.conditions.ConditionPlayerHasCastle;
|
||||
import com.l2jmobius.gameserver.model.conditions.ConditionPlayerHasClanHall;
|
||||
import com.l2jmobius.gameserver.model.conditions.ConditionPlayerHasFort;
|
||||
@ -511,12 +510,6 @@ public abstract class DocumentBase
|
||||
cond = joinAnd(cond, new ConditionPlayerCp(cp));
|
||||
break;
|
||||
}
|
||||
case "grade":
|
||||
{
|
||||
final int expIndex = Integer.decode(getValue(a.getNodeValue(), template));
|
||||
cond = joinAnd(cond, new ConditionPlayerGrade(expIndex));
|
||||
break;
|
||||
}
|
||||
case "pkcount":
|
||||
{
|
||||
final int expIndex = Integer.decode(getValue(a.getNodeValue(), template));
|
||||
|
@ -182,7 +182,7 @@ public class Fishing
|
||||
return;
|
||||
}
|
||||
|
||||
if (_player.isInCraftMode() || _player.isInStoreMode())
|
||||
if (_player.isCrafting() || _player.isInStoreMode())
|
||||
{
|
||||
_player.sendPacket(SystemMessageId.YOU_CANNOT_FISH_WHILE_USING_A_RECIPE_BOOK_PRIVATE_WORKSHOP_OR_PRIVATE_STORE);
|
||||
_player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
@ -1,57 +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;
|
||||
|
||||
/**
|
||||
* This class describes a RecipeList component (1 line of the recipe : Item-Quantity needed).
|
||||
*/
|
||||
public class L2RecipeInstance
|
||||
{
|
||||
/** The Identifier of the item needed in the L2RecipeInstance */
|
||||
private final int _itemId;
|
||||
|
||||
/** The item quantity needed in the L2RecipeInstance */
|
||||
private final int _quantity;
|
||||
|
||||
/**
|
||||
* Constructor of L2RecipeInstance (create a new line in a RecipeList).
|
||||
* @param itemId
|
||||
* @param quantity
|
||||
*/
|
||||
public L2RecipeInstance(int itemId, int quantity)
|
||||
{
|
||||
_itemId = itemId;
|
||||
_quantity = quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Identifier of the L2RecipeInstance Item needed.
|
||||
*/
|
||||
public int getItemId()
|
||||
{
|
||||
return _itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Item quantity needed of the L2RecipeInstance.
|
||||
*/
|
||||
public int getQuantity()
|
||||
{
|
||||
return _quantity;
|
||||
}
|
||||
|
||||
}
|
@ -1,242 +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;
|
||||
|
||||
/**
|
||||
* This class describes a Recipe used by Dwarf to craft Item. All L2RecipeList are made of L2RecipeInstance (1 line of the recipe : Item-Quantity needed).
|
||||
*/
|
||||
public class L2RecipeList
|
||||
{
|
||||
/** The table containing all L2RecipeInstance (1 line of the recipe : Item-Quantity needed) of the L2RecipeList */
|
||||
private L2RecipeInstance[] _recipes;
|
||||
|
||||
/** The table containing all L2RecipeStatInstance for the statUse parameter of the L2RecipeList */
|
||||
private L2RecipeStatInstance[] _statUse;
|
||||
|
||||
/** The table containing all L2RecipeStatInstance for the altStatChange parameter of the L2RecipeList */
|
||||
private L2RecipeStatInstance[] _altStatChange;
|
||||
|
||||
/** The Identifier of the Instance */
|
||||
private final int _id;
|
||||
|
||||
/** The crafting level needed to use this L2RecipeList */
|
||||
private final int _level;
|
||||
|
||||
/** The Identifier of the L2RecipeList */
|
||||
private final int _recipeId;
|
||||
|
||||
/** The name of the L2RecipeList */
|
||||
private final String _recipeName;
|
||||
|
||||
/** The crafting success rate when using the L2RecipeList */
|
||||
private final int _successRate;
|
||||
|
||||
/** The Identifier of the Item crafted with this L2RecipeList */
|
||||
private final int _itemId;
|
||||
|
||||
/** The quantity of Item crafted when using this L2RecipeList */
|
||||
private final int _count;
|
||||
|
||||
/** The Identifier of the Rare Item crafted with this L2RecipeList */
|
||||
private int _rareItemId;
|
||||
|
||||
/** The quantity of Rare Item crafted when using this L2RecipeList */
|
||||
private int _rareCount;
|
||||
|
||||
/** The chance of Rare Item crafted when using this L2RecipeList */
|
||||
private int _rarity;
|
||||
|
||||
/** If this a common or a dwarven recipe */
|
||||
private final boolean _isDwarvenRecipe;
|
||||
|
||||
/**
|
||||
* Constructor of L2RecipeList (create a new Recipe).
|
||||
* @param set
|
||||
* @param haveRare
|
||||
*/
|
||||
public L2RecipeList(StatsSet set, boolean haveRare)
|
||||
{
|
||||
_recipes = new L2RecipeInstance[0];
|
||||
_statUse = new L2RecipeStatInstance[0];
|
||||
_altStatChange = new L2RecipeStatInstance[0];
|
||||
_id = set.getInt("id");
|
||||
_level = set.getInt("craftLevel");
|
||||
_recipeId = set.getInt("recipeId");
|
||||
_recipeName = set.getString("recipeName");
|
||||
_successRate = set.getInt("successRate");
|
||||
_itemId = set.getInt("itemId");
|
||||
_count = set.getInt("count");
|
||||
if (haveRare)
|
||||
{
|
||||
_rareItemId = set.getInt("rareItemId");
|
||||
_rareCount = set.getInt("rareCount");
|
||||
_rarity = set.getInt("rarity");
|
||||
}
|
||||
_isDwarvenRecipe = set.getBoolean("isDwarvenRecipe");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a L2RecipeInstance to the L2RecipeList (add a line Item-Quantity needed to the Recipe).
|
||||
* @param recipe
|
||||
*/
|
||||
public void addRecipe(L2RecipeInstance recipe)
|
||||
{
|
||||
final int len = _recipes.length;
|
||||
final L2RecipeInstance[] tmp = new L2RecipeInstance[len + 1];
|
||||
System.arraycopy(_recipes, 0, tmp, 0, len);
|
||||
tmp[len] = recipe;
|
||||
_recipes = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a L2RecipeStatInstance of the statUse parameter to the L2RecipeList.
|
||||
* @param statUse
|
||||
*/
|
||||
public void addStatUse(L2RecipeStatInstance statUse)
|
||||
{
|
||||
final int len = _statUse.length;
|
||||
final L2RecipeStatInstance[] tmp = new L2RecipeStatInstance[len + 1];
|
||||
System.arraycopy(_statUse, 0, tmp, 0, len);
|
||||
tmp[len] = statUse;
|
||||
_statUse = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a L2RecipeStatInstance of the altStatChange parameter to the L2RecipeList.
|
||||
* @param statChange
|
||||
*/
|
||||
public void addAltStatChange(L2RecipeStatInstance statChange)
|
||||
{
|
||||
final int len = _altStatChange.length;
|
||||
final L2RecipeStatInstance[] tmp = new L2RecipeStatInstance[len + 1];
|
||||
System.arraycopy(_altStatChange, 0, tmp, 0, len);
|
||||
tmp[len] = statChange;
|
||||
_altStatChange = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Identifier of the Instance.
|
||||
*/
|
||||
public int getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the crafting level needed to use this L2RecipeList.
|
||||
*/
|
||||
public int getLevel()
|
||||
{
|
||||
return _level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Identifier of the L2RecipeList.
|
||||
*/
|
||||
public int getRecipeId()
|
||||
{
|
||||
return _recipeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the L2RecipeList.
|
||||
*/
|
||||
public String getRecipeName()
|
||||
{
|
||||
return _recipeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the crafting success rate when using the L2RecipeList.
|
||||
*/
|
||||
public int getSuccessRate()
|
||||
{
|
||||
return _successRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Identifier of the Item crafted with this L2RecipeList.
|
||||
*/
|
||||
public int getItemId()
|
||||
{
|
||||
return _itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the quantity of Item crafted when using this L2RecipeList.
|
||||
*/
|
||||
public int getCount()
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Identifier of the Rare Item crafted with this L2RecipeList.
|
||||
*/
|
||||
public int getRareItemId()
|
||||
{
|
||||
return _rareItemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the quantity of Rare Item crafted when using this L2RecipeList.
|
||||
*/
|
||||
public int getRareCount()
|
||||
{
|
||||
return _rareCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the chance of Rare Item crafted when using this L2RecipeList.
|
||||
*/
|
||||
public int getRarity()
|
||||
{
|
||||
return _rarity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if this a Dwarven recipe or {@code false} if its a Common recipe
|
||||
*/
|
||||
public boolean isDwarvenRecipe()
|
||||
{
|
||||
return _isDwarvenRecipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the table containing all L2RecipeInstance (1 line of the recipe : Item-Quantity needed) of the L2RecipeList.
|
||||
*/
|
||||
public L2RecipeInstance[] getRecipes()
|
||||
{
|
||||
return _recipes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the table containing all L2RecipeStatInstance of the statUse parameter of the L2RecipeList.
|
||||
*/
|
||||
public L2RecipeStatInstance[] getStatUse()
|
||||
{
|
||||
return _statUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the table containing all L2RecipeStatInstance of the AltStatChange parameter of the L2RecipeList.
|
||||
*/
|
||||
public L2RecipeStatInstance[] getAltStatChange()
|
||||
{
|
||||
return _altStatChange;
|
||||
}
|
||||
}
|
@ -1,59 +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;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.StatType;
|
||||
|
||||
/**
|
||||
* This class describes a RecipeList statUse and altStatChange component.
|
||||
*/
|
||||
public class L2RecipeStatInstance
|
||||
{
|
||||
/** The Identifier of the statType */
|
||||
private final StatType _type;
|
||||
|
||||
/** The value of the statType */
|
||||
private final int _value;
|
||||
|
||||
/**
|
||||
* Constructor of L2RecipeStatInstance.
|
||||
* @param type
|
||||
* @param value
|
||||
*/
|
||||
public L2RecipeStatInstance(String type, int value)
|
||||
{
|
||||
_type = Enum.valueOf(StatType.class, type);
|
||||
_value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the the type of the L2RecipeStatInstance.
|
||||
*/
|
||||
public StatType getType()
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of the L2RecipeStatInstance.
|
||||
*/
|
||||
public int getValue()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
}
|
@ -32,8 +32,8 @@ public final class L2Seed
|
||||
private final boolean _isAlternative;
|
||||
private final int _limitSeeds;
|
||||
private final int _limitCrops;
|
||||
private final int _seedReferencePrice;
|
||||
private final int _cropReferencePrice;
|
||||
private final long _seedReferencePrice;
|
||||
private final long _cropReferencePrice;
|
||||
|
||||
public L2Seed(StatsSet set)
|
||||
{
|
||||
@ -99,27 +99,27 @@ public final class L2Seed
|
||||
return _limitCrops * Config.RATE_DROP_MANOR;
|
||||
}
|
||||
|
||||
public final int getSeedReferencePrice()
|
||||
public final long getSeedReferencePrice()
|
||||
{
|
||||
return _seedReferencePrice;
|
||||
}
|
||||
|
||||
public final int getSeedMaxPrice()
|
||||
public final long getSeedMaxPrice()
|
||||
{
|
||||
return _seedReferencePrice * 10;
|
||||
}
|
||||
|
||||
public final int getSeedMinPrice()
|
||||
public final long getSeedMinPrice()
|
||||
{
|
||||
return (int) (_seedReferencePrice * 0.6);
|
||||
}
|
||||
|
||||
public final int getCropReferencePrice()
|
||||
public final long getCropReferencePrice()
|
||||
{
|
||||
return _cropReferencePrice;
|
||||
}
|
||||
|
||||
public final int getCropMaxPrice()
|
||||
public final long getCropMaxPrice()
|
||||
{
|
||||
return _cropReferencePrice * 10;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public final class TempItem
|
||||
{
|
||||
private final int _itemId;
|
||||
private int _quantity;
|
||||
private final int _referencePrice;
|
||||
private final long _referencePrice;
|
||||
private final String _itemName;
|
||||
|
||||
/**
|
||||
@ -60,7 +60,7 @@ public final class TempItem
|
||||
_quantity = quantity;
|
||||
}
|
||||
|
||||
public int getReferencePrice()
|
||||
public long getReferencePrice()
|
||||
{
|
||||
return _referencePrice;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -46,11 +45,11 @@ import java.util.stream.Collectors;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.GameTimeController;
|
||||
import com.l2jmobius.gameserver.ItemsAutoDestroy;
|
||||
import com.l2jmobius.gameserver.LoginServerThread;
|
||||
import com.l2jmobius.gameserver.RecipeController;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.ai.L2CharacterAI;
|
||||
@ -63,6 +62,7 @@ import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.CharSummonTable;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.CategoryData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ClassListData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.HennaData;
|
||||
@ -85,6 +85,7 @@ import com.l2jmobius.gameserver.enums.GroupType;
|
||||
import com.l2jmobius.gameserver.enums.HtmlActionScope;
|
||||
import com.l2jmobius.gameserver.enums.IllegalActionPunishmentType;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.enums.ItemGrade;
|
||||
import com.l2jmobius.gameserver.enums.MountType;
|
||||
import com.l2jmobius.gameserver.enums.NextActionType;
|
||||
import com.l2jmobius.gameserver.enums.PartyDistributionType;
|
||||
@ -116,6 +117,7 @@ import com.l2jmobius.gameserver.instancemanager.MatchingRoomManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MentorManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.PunishmentManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.SellBuffsManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.SiegeManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.ArenaParticipantsHolder;
|
||||
@ -128,7 +130,6 @@ import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2ClanMember;
|
||||
import com.l2jmobius.gameserver.model.L2CommandChannel;
|
||||
import com.l2jmobius.gameserver.model.L2ContactList;
|
||||
import com.l2jmobius.gameserver.model.L2ManufactureItem;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2Party;
|
||||
import com.l2jmobius.gameserver.model.L2Party.MessageType;
|
||||
@ -136,7 +137,6 @@ import com.l2jmobius.gameserver.model.L2PetData;
|
||||
import com.l2jmobius.gameserver.model.L2PetLevelData;
|
||||
import com.l2jmobius.gameserver.model.L2PremiumItem;
|
||||
import com.l2jmobius.gameserver.model.L2Radar;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeList;
|
||||
import com.l2jmobius.gameserver.model.L2Request;
|
||||
import com.l2jmobius.gameserver.model.L2SkillLearn;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
@ -163,7 +163,6 @@ import com.l2jmobius.gameserver.model.actor.stat.PcStat;
|
||||
import com.l2jmobius.gameserver.model.actor.status.PcStatus;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.DismountTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.FameTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.GameGuardCheckTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.HennaDurationTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.InventoryEnableTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.PetFeedTask;
|
||||
@ -180,8 +179,6 @@ import com.l2jmobius.gameserver.model.actor.tasks.player.WaterTask;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2PcTemplate;
|
||||
import com.l2jmobius.gameserver.model.actor.transform.Transform;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.base.ClassLevel;
|
||||
import com.l2jmobius.gameserver.model.base.PlayerClass;
|
||||
import com.l2jmobius.gameserver.model.base.SubClass;
|
||||
import com.l2jmobius.gameserver.model.ceremonyofchaos.CeremonyOfChaosEvent;
|
||||
import com.l2jmobius.gameserver.model.cubic.CubicInstance;
|
||||
@ -215,6 +212,7 @@ import com.l2jmobius.gameserver.model.holders.MonsterBookCardHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MonsterBookRewardHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MovieHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PlayerEventHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.SellBuffHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillUseHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.TrainingHolder;
|
||||
@ -235,6 +233,7 @@ import com.l2jmobius.gameserver.model.items.L2Weapon;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.items.type.ActionType;
|
||||
import com.l2jmobius.gameserver.model.items.type.ArmorType;
|
||||
import com.l2jmobius.gameserver.model.items.type.CrystalType;
|
||||
import com.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||
import com.l2jmobius.gameserver.model.items.type.WeaponType;
|
||||
import com.l2jmobius.gameserver.model.matching.MatchingRoom;
|
||||
@ -293,7 +292,6 @@ import com.l2jmobius.gameserver.network.serverpackets.ExUseSharedGroupItem;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoAbnormalVisualEffect;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoCubic;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.GameGuardQuery;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.GetOnVehicle;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.HennaInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
@ -523,13 +521,13 @@ public final class L2PcInstance extends L2Playable
|
||||
private AdminTeleportType _teleportType = AdminTeleportType.NORMAL;
|
||||
|
||||
private boolean _inCrystallize;
|
||||
private boolean _inCraftMode;
|
||||
private volatile boolean _isCrafting;
|
||||
|
||||
private long _offlineShopStart = 0;
|
||||
|
||||
/** The table containing all L2RecipeList of the L2PcInstance */
|
||||
private final Map<Integer, L2RecipeList> _dwarvenRecipeBook = new ConcurrentSkipListMap<>();
|
||||
private final Map<Integer, L2RecipeList> _commonRecipeBook = new ConcurrentSkipListMap<>();
|
||||
private final Map<Integer, RecipeHolder> _dwarvenRecipeBook = new ConcurrentSkipListMap<>();
|
||||
private final Map<Integer, RecipeHolder> _commonRecipeBook = new ConcurrentSkipListMap<>();
|
||||
|
||||
/** Premium Items */
|
||||
private final Map<Integer, L2PremiumItem> _premiumItems = new ConcurrentSkipListMap<>();
|
||||
@ -564,7 +562,7 @@ public final class L2PcInstance extends L2Playable
|
||||
|
||||
private TradeList _activeTradeList;
|
||||
private ItemContainer _activeWarehouse;
|
||||
private volatile Map<Integer, L2ManufactureItem> _manufactureItems;
|
||||
private volatile Map<Integer, Long> _manufactureItems;
|
||||
private String _storeName = "";
|
||||
private TradeList _sellList;
|
||||
private TradeList _buyList;
|
||||
@ -619,8 +617,6 @@ public final class L2PcInstance extends L2Playable
|
||||
// after Freya players can control more than one tamed beast
|
||||
private volatile Set<L2TamedBeastInstance> _tamedBeast = null;
|
||||
|
||||
private boolean _minimapAllowed = false;
|
||||
|
||||
// client radar
|
||||
// TODO: This needs to be better integrated and saved/loaded
|
||||
private final L2Radar _radar;
|
||||
@ -712,6 +708,10 @@ public final class L2PcInstance extends L2Playable
|
||||
|
||||
// private byte _updateKnownCounter = 0;
|
||||
|
||||
private int _createItemLevel;
|
||||
private int _createCommonItemLevel;
|
||||
private ItemGrade _crystallizeGrade = ItemGrade.NONE;
|
||||
private CrystalType _expertiseLevel = CrystalType.NONE;
|
||||
private int _expertiseArmorPenalty = 0;
|
||||
private int _expertiseWeaponPenalty = 0;
|
||||
private int _expertisePenaltyBonus = 0;
|
||||
@ -1259,14 +1259,14 @@ public final class L2PcInstance extends L2Playable
|
||||
return getPrivateStoreType() != PrivateStoreType.NONE;
|
||||
}
|
||||
|
||||
public boolean isInCraftMode()
|
||||
public boolean isCrafting()
|
||||
{
|
||||
return _inCraftMode;
|
||||
return _isCrafting;
|
||||
}
|
||||
|
||||
public void isInCraftMode(boolean b)
|
||||
public void setIsCrafting(boolean isCrafting)
|
||||
{
|
||||
_inCraftMode = b;
|
||||
_isCrafting = isCrafting;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1304,17 +1304,17 @@ public final class L2PcInstance extends L2Playable
|
||||
/**
|
||||
* @return a table containing all Common L2RecipeList of the L2PcInstance.
|
||||
*/
|
||||
public L2RecipeList[] getCommonRecipeBook()
|
||||
public Collection<RecipeHolder> getCommonRecipeBook()
|
||||
{
|
||||
return _commonRecipeBook.values().toArray(new L2RecipeList[_commonRecipeBook.values().size()]);
|
||||
return _commonRecipeBook.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a table containing all Dwarf L2RecipeList of the L2PcInstance.
|
||||
*/
|
||||
public L2RecipeList[] getDwarvenRecipeBook()
|
||||
public Collection<RecipeHolder> getDwarvenRecipeBook()
|
||||
{
|
||||
return _dwarvenRecipeBook.values().toArray(new L2RecipeList[_dwarvenRecipeBook.values().size()]);
|
||||
return _dwarvenRecipeBook.values();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1322,7 +1322,7 @@ public final class L2PcInstance extends L2Playable
|
||||
* @param recipe The L2RecipeList to add to the _recipebook
|
||||
* @param saveToDb
|
||||
*/
|
||||
public void registerCommonRecipeList(L2RecipeList recipe, boolean saveToDb)
|
||||
public void registerCommonRecipeList(RecipeHolder recipe, boolean saveToDb)
|
||||
{
|
||||
_commonRecipeBook.put(recipe.getId(), recipe);
|
||||
|
||||
@ -1337,7 +1337,7 @@ public final class L2PcInstance extends L2Playable
|
||||
* @param recipe The L2RecipeList to add to the _recipebook
|
||||
* @param saveToDb
|
||||
*/
|
||||
public void registerDwarvenRecipeList(L2RecipeList recipe, boolean saveToDb)
|
||||
public void registerDwarvenRecipeList(RecipeHolder recipe, boolean saveToDb)
|
||||
{
|
||||
_dwarvenRecipeBook.put(recipe.getId(), recipe);
|
||||
|
||||
@ -1867,29 +1867,39 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the L2PcInstance can Craft Dwarven Recipes.
|
||||
* @return the maximum dwarven recipe level this character can craft.
|
||||
*/
|
||||
public boolean hasDwarvenCraft()
|
||||
public int getCreateItemLevel()
|
||||
{
|
||||
return getSkillLevel(CommonSkill.CREATE_DWARVEN.getId()) >= 1;
|
||||
return _createItemLevel;
|
||||
}
|
||||
|
||||
public int getDwarvenCraft()
|
||||
public void setCreateItemLevel(int createItemLevel)
|
||||
{
|
||||
return getSkillLevel(CommonSkill.CREATE_DWARVEN.getId());
|
||||
_createItemLevel = createItemLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the L2PcInstance can Craft Dwarven Recipes.
|
||||
* @return the maximum common recipe level this character can craft.
|
||||
*/
|
||||
public boolean hasCommonCraft()
|
||||
public int getCreateCommonItemLevel()
|
||||
{
|
||||
return getSkillLevel(CommonSkill.CREATE_COMMON.getId()) >= 1;
|
||||
return _createCommonItemLevel;
|
||||
}
|
||||
|
||||
public int getCommonCraft()
|
||||
public void setCreateCommonItemLevel(int createCommonItemLevel)
|
||||
{
|
||||
return getSkillLevel(CommonSkill.CREATE_COMMON.getId());
|
||||
_createCommonItemLevel = createCommonItemLevel;
|
||||
}
|
||||
|
||||
public ItemGrade getCrystallizeGrade()
|
||||
{
|
||||
return _crystallizeGrade;
|
||||
}
|
||||
|
||||
public void setCrystallizeGrade(ItemGrade crystallizeGrade)
|
||||
{
|
||||
_crystallizeGrade = crystallizeGrade != null ? crystallizeGrade : ItemGrade.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2073,11 +2083,7 @@ public final class L2PcInstance extends L2Playable
|
||||
|
||||
public int getWeightPenalty()
|
||||
{
|
||||
if (_dietMode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return _curWeightPenalty;
|
||||
return _dietMode ? 0 : _curWeightPenalty;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2141,37 +2147,26 @@ public final class L2PcInstance extends L2Playable
|
||||
return;
|
||||
}
|
||||
|
||||
final int expertiseLevel = getExpertiseLevel();
|
||||
final CrystalType expertiseLevel = getExpertiseLevel().plusLevel(getExpertisePenaltyBonus());
|
||||
|
||||
int armorPenalty = 0;
|
||||
int weaponPenalty = 0;
|
||||
int crystaltype;
|
||||
|
||||
for (L2ItemInstance item : getInventory().getItems())
|
||||
for (L2ItemInstance item : getInventory().getPaperdollItems(item -> (item != null) && ((item.getItemType() != EtcItemType.ARROW) && (item.getItemType() != EtcItemType.BOLT)) && item.getItem().getCrystalType().isGreater(expertiseLevel)))
|
||||
{
|
||||
if ((item != null) && item.isEquipped() && ((item.getItemType() != EtcItemType.ARROW) && (item.getItemType() != EtcItemType.BOLT)))
|
||||
if (item.isArmor())
|
||||
{
|
||||
crystaltype = item.getItem().getCrystalType().getId();
|
||||
if (crystaltype > expertiseLevel)
|
||||
{
|
||||
if (item.isWeapon() && (crystaltype > weaponPenalty))
|
||||
{
|
||||
weaponPenalty = crystaltype;
|
||||
}
|
||||
else if (crystaltype > armorPenalty)
|
||||
{
|
||||
armorPenalty = crystaltype;
|
||||
}
|
||||
}
|
||||
// Armor penalty level increases depending on amount of penalty armors equipped, not grade level difference.
|
||||
armorPenalty = CommonUtil.constrain(armorPenalty + 1, 0, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Weapon penalty level increases based on grade difference.
|
||||
weaponPenalty = CommonUtil.constrain(item.getItem().getCrystalType().getLevel() - expertiseLevel.getLevel(), 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
final int bonus = getExpertisePenaltyBonus();
|
||||
|
||||
// calc weapon penalty
|
||||
weaponPenalty = weaponPenalty - expertiseLevel - bonus;
|
||||
weaponPenalty = Math.min(Math.max(weaponPenalty, 0), 4);
|
||||
|
||||
if ((getExpertiseWeaponPenalty() != weaponPenalty) || (getSkillLevel(CommonSkill.WEAPON_GRADE_PENALTY.getId()) != weaponPenalty))
|
||||
{
|
||||
@ -2182,15 +2177,11 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
else
|
||||
{
|
||||
removeSkill(getKnownSkill(CommonSkill.WEAPON_GRADE_PENALTY.getId()), false, true);
|
||||
removeSkill(CommonSkill.WEAPON_GRADE_PENALTY.getId(), true);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// calc armor penalty
|
||||
armorPenalty = armorPenalty - expertiseLevel - bonus;
|
||||
armorPenalty = Math.min(Math.max(armorPenalty, 0), 4);
|
||||
|
||||
if ((getExpertiseArmorPenalty() != armorPenalty) || (getSkillLevel(CommonSkill.ARMOR_GRADE_PENALTY.getId()) != armorPenalty))
|
||||
{
|
||||
_expertiseArmorPenalty = armorPenalty;
|
||||
@ -2200,13 +2191,14 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
else
|
||||
{
|
||||
removeSkill(getKnownSkill(CommonSkill.ARMOR_GRADE_PENALTY.getId()), false, true);
|
||||
removeSkill(CommonSkill.ARMOR_GRADE_PENALTY.getId(), true);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
sendSkillList(); // Update expertise penalty icon in skill list.
|
||||
sendPacket(new EtcStatusUpdate(this));
|
||||
}
|
||||
}
|
||||
@ -2383,7 +2375,7 @@ public final class L2PcInstance extends L2Playable
|
||||
|
||||
try
|
||||
{
|
||||
if ((getLvlJoinedAcademy() != 0) && (_clan != null) && (PlayerClass.values()[Id].getLevel() == ClassLevel.THIRD))
|
||||
if ((getLvlJoinedAcademy() != 0) && (_clan != null) && CategoryData.getInstance().isInCategory(CategoryType.THIRD_CLASS_GROUP, Id))
|
||||
{
|
||||
if (getLvlJoinedAcademy() <= 16)
|
||||
{
|
||||
@ -2416,7 +2408,7 @@ public final class L2PcInstance extends L2Playable
|
||||
setTarget(this);
|
||||
broadcastPacket(new MagicSkillUse(this, 5103, 1, 1000, 0));
|
||||
setClassTemplate(Id);
|
||||
if (getClassId().level() == 3)
|
||||
if (isInCategory(CategoryType.FOURTH_CLASS_GROUP))
|
||||
{
|
||||
sendPacket(SystemMessageId.CONGRATULATIONS_YOU_VE_COMPLETED_YOUR_THIRD_CLASS_TRANSFER_QUEST);
|
||||
}
|
||||
@ -2710,18 +2702,6 @@ public final class L2PcInstance extends L2Playable
|
||||
return _radar;
|
||||
}
|
||||
|
||||
/* Return true if Hellbound minimap allowed */
|
||||
public boolean isMinimapAllowed()
|
||||
{
|
||||
return _minimapAllowed;
|
||||
}
|
||||
|
||||
/* Enable or disable minimap on Hellbound */
|
||||
public void setMinimapAllowed(boolean b)
|
||||
{
|
||||
_minimapAllowed = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the SP amount of the L2PcInstance.
|
||||
*/
|
||||
@ -4355,6 +4335,8 @@ public final class L2PcInstance extends L2Playable
|
||||
return getClan().getAllyCrestId();
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
/*
|
||||
public void queryGameGuard()
|
||||
{
|
||||
if (getClient() != null)
|
||||
@ -4364,9 +4346,10 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
if (Config.GAMEGUARD_ENFORCE)
|
||||
{
|
||||
ThreadPoolManager.schedule(new GameGuardCheckTask(this), 30 * 1000);
|
||||
ThreadPool.scheduleGeneral(new GameGuardCheckTask(this), 30 * 1000);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
//@formatter:on
|
||||
|
||||
/**
|
||||
* Send a Server->Client packet StatusUpdate to the L2PcInstance.
|
||||
@ -4404,22 +4387,28 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
if (target instanceof L2PcInstance)
|
||||
{
|
||||
final L2PcInstance temp = (L2PcInstance) target;
|
||||
final L2PcInstance targetPlayer = (L2PcInstance) target;
|
||||
sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
||||
if ((temp.getPrivateStoreType() == PrivateStoreType.SELL) || (temp.getPrivateStoreType() == PrivateStoreType.PACKAGE_SELL))
|
||||
if ((targetPlayer.getPrivateStoreType() == PrivateStoreType.SELL) || (targetPlayer.getPrivateStoreType() == PrivateStoreType.PACKAGE_SELL))
|
||||
{
|
||||
sendPacket(new PrivateStoreListSell(this, temp));
|
||||
if (isSellingBuffs())
|
||||
{
|
||||
SellBuffsManager.getInstance().sendBuffMenu(this, targetPlayer, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendPacket(new PrivateStoreListSell(this, targetPlayer));
|
||||
}
|
||||
}
|
||||
else if (temp.getPrivateStoreType() == PrivateStoreType.BUY)
|
||||
else if (targetPlayer.getPrivateStoreType() == PrivateStoreType.BUY)
|
||||
{
|
||||
sendPacket(new PrivateStoreListBuy(this, temp));
|
||||
sendPacket(new PrivateStoreListBuy(this, targetPlayer));
|
||||
}
|
||||
else if (temp.getPrivateStoreType() == PrivateStoreType.MANUFACTURE)
|
||||
else if (targetPlayer.getPrivateStoreType() == PrivateStoreType.MANUFACTURE)
|
||||
{
|
||||
sendPacket(new RecipeShopSellList(this, temp));
|
||||
sendPacket(new RecipeShopSellList(this, targetPlayer));
|
||||
}
|
||||
|
||||
}
|
||||
else if (target != null) // _interactTarget=null should never happen but one never knows ^^;
|
||||
{
|
||||
@ -5057,6 +5046,9 @@ public final class L2PcInstance extends L2Playable
|
||||
// Clear resurrect xp calculation
|
||||
setExpBeforeDeath(0);
|
||||
|
||||
// Calculate Shilen's Breath debuff level. It must happen right before death, because buffs aren't applied on dead characters.
|
||||
calculateShilensBreathDebuffLevel(killer);
|
||||
|
||||
// Kill the L2PcInstance
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
@ -5110,9 +5102,6 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
}
|
||||
|
||||
// calculate Shilen's Breath debuff level
|
||||
calculateShilensBreathDebuffLevel(killer);
|
||||
|
||||
if (isMounted())
|
||||
{
|
||||
stopFeed();
|
||||
@ -5778,21 +5767,21 @@ public final class L2PcInstance extends L2Playable
|
||||
* Get the manufacture items map of this player.
|
||||
* @return the the manufacture items map
|
||||
*/
|
||||
public Map<Integer, L2ManufactureItem> getManufactureItems()
|
||||
public Map<Integer, Long> getManufactureItems()
|
||||
{
|
||||
if (_manufactureItems == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_manufactureItems == null)
|
||||
{
|
||||
_manufactureItems = Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
}
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
return _manufactureItems;
|
||||
}
|
||||
|
||||
public void setManufactureItems(Map<Integer, Long> manufactureItems)
|
||||
{
|
||||
_manufactureItems = manufactureItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the store name, if any.
|
||||
* @return the store name
|
||||
@ -6524,7 +6513,7 @@ public final class L2PcInstance extends L2Playable
|
||||
statement.setInt(23, getRace().ordinal());
|
||||
statement.setInt(24, getClassId().getId());
|
||||
statement.setLong(25, getDeleteTimer());
|
||||
statement.setInt(26, hasDwarvenCraft() ? 1 : 0);
|
||||
statement.setInt(26, getCreateItemLevel() > 0 ? 1 : 0);
|
||||
statement.setString(27, getTitle());
|
||||
statement.setInt(28, getAppearance().getTitleColor());
|
||||
statement.setInt(29, isOnlineInt());
|
||||
@ -6994,11 +6983,11 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
_dwarvenRecipeBook.clear();
|
||||
|
||||
L2RecipeList recipe;
|
||||
final RecipeData rd = RecipeData.getInstance();
|
||||
RecipeHolder recipe;
|
||||
RecipeData rd = RecipeData.getInstance();
|
||||
while (rset.next())
|
||||
{
|
||||
recipe = rd.getRecipeList(rset.getInt("id"));
|
||||
recipe = rd.getRecipe(rset.getInt("id"));
|
||||
if (loadCommon)
|
||||
{
|
||||
if (rset.getInt(2) == 1)
|
||||
@ -8770,7 +8759,7 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
for (int itemId : _activeSoulShots)
|
||||
{
|
||||
if (ItemTable.getInstance().getTemplate(itemId).getCrystalType().getId() == crystalType)
|
||||
if (ItemTable.getInstance().getTemplate(itemId).getCrystalType().getLevel() == crystalType)
|
||||
{
|
||||
disableAutoShot(itemId);
|
||||
}
|
||||
@ -10290,17 +10279,17 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
|
||||
/**
|
||||
* Expertise of the L2PcInstance (None=0, D=1, C=2, B=3, A=4, S=5, S80=6, S84=7)
|
||||
* @return int Expertise skill level.
|
||||
* Expertise of the L2PcInstance (None=0, D=1, C=2, B=3, A=4, S=5, S80=6, S84=7, R=8, R95=9, R99=10)
|
||||
* @return CrystalTyperepresenting expertise level..
|
||||
*/
|
||||
public int getExpertiseLevel()
|
||||
public CrystalType getExpertiseLevel()
|
||||
{
|
||||
int level = getSkillLevel(239);
|
||||
if (level < 0)
|
||||
{
|
||||
level = 0;
|
||||
}
|
||||
return level;
|
||||
return _expertiseLevel;
|
||||
}
|
||||
|
||||
public void setExpertiseLevel(CrystalType crystalType)
|
||||
{
|
||||
_expertiseLevel = crystalType != null ? crystalType : CrystalType.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -10864,16 +10853,6 @@ public final class L2PcInstance extends L2Playable
|
||||
_log.log(Level.SEVERE, "deleteMe()", e);
|
||||
}
|
||||
|
||||
// Stop crafting, if in progress
|
||||
try
|
||||
{
|
||||
RecipeController.getInstance().requestMakeItemAbort(this);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "deleteMe()", e);
|
||||
}
|
||||
|
||||
// Cancel Attak or Cast
|
||||
try
|
||||
{
|
||||
@ -12501,11 +12480,11 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
final AtomicInteger slot = new AtomicInteger(1);
|
||||
con.setAutoCommit(false);
|
||||
for (L2ManufactureItem item : _manufactureItems.values())
|
||||
for (Entry<Integer, Long> entry : _manufactureItems.entrySet())
|
||||
{
|
||||
st.setInt(1, getObjectId());
|
||||
st.setInt(2, item.getRecipeId());
|
||||
st.setLong(3, item.getCost());
|
||||
st.setInt(2, entry.getKey());
|
||||
st.setLong(3, entry.getValue());
|
||||
st.setInt(4, slot.getAndIncrement());
|
||||
st.addBatch();
|
||||
}
|
||||
@ -12522,10 +12501,7 @@ public final class L2PcInstance extends L2Playable
|
||||
|
||||
private void restoreRecipeShopList()
|
||||
{
|
||||
if (_manufactureItems != null)
|
||||
{
|
||||
_manufactureItems.clear();
|
||||
}
|
||||
final Map<Integer, Long> manufactureItems = new HashMap<>();
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_RECIPE_SHOP))
|
||||
@ -12535,7 +12511,7 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
while (rset.next())
|
||||
{
|
||||
getManufactureItems().put(rset.getInt("recipeId"), new L2ManufactureItem(rset.getInt("recipeId"), rset.getLong("price")));
|
||||
manufactureItems.put(rset.getInt("recipeId"), rset.getLong("price"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12543,6 +12519,8 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
_log.log(Level.SEVERE, "Could not restore recipe shop list data for playerId: " + getObjectId(), e);
|
||||
}
|
||||
|
||||
_manufactureItems = manufactureItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,7 +78,7 @@ public class PcStatus extends PlayableStatus
|
||||
}
|
||||
|
||||
// If OFFLINE_MODE_NO_DAMAGE is enabled and player is offline and he is in store/craft mode, no damage is taken.
|
||||
if (Config.OFFLINE_MODE_NO_DAMAGE && (getActiveChar().getClient() != null) && getActiveChar().getClient().isDetached() && ((Config.OFFLINE_TRADE_ENABLE && ((getActiveChar().getPrivateStoreType() == PrivateStoreType.SELL) || (getActiveChar().getPrivateStoreType() == PrivateStoreType.BUY))) || (Config.OFFLINE_CRAFT_ENABLE && (getActiveChar().isInCraftMode() || (getActiveChar().getPrivateStoreType() == PrivateStoreType.MANUFACTURE)))))
|
||||
if (Config.OFFLINE_MODE_NO_DAMAGE && (getActiveChar().getClient() != null) && getActiveChar().getClient().isDetached() && ((Config.OFFLINE_TRADE_ENABLE && ((getActiveChar().getPrivateStoreType() == PrivateStoreType.SELL) || (getActiveChar().getPrivateStoreType() == PrivateStoreType.BUY))) || (Config.OFFLINE_CRAFT_ENABLE && (getActiveChar().isCrafting() || (getActiveChar().getPrivateStoreType() == PrivateStoreType.MANUFACTURE)))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -100,7 +100,7 @@ public class PcStatus extends PlayableStatus
|
||||
getActiveChar().stopEffectsOnDamage();
|
||||
}
|
||||
// Attacked players in craft/shops stand up.
|
||||
if (getActiveChar().isInCraftMode() || getActiveChar().isInStoreMode())
|
||||
if (getActiveChar().isCrafting() || getActiveChar().isInStoreMode())
|
||||
{
|
||||
getActiveChar().setPrivateStoreType(PrivateStoreType.NONE);
|
||||
getActiveChar().standUp();
|
||||
|
@ -1,61 +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.conditions;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* The Class ConditionPlayerGrade.
|
||||
* @author Gigiikun
|
||||
*/
|
||||
public final class ConditionPlayerGrade extends Condition
|
||||
{
|
||||
protected static final Logger _log = Logger.getLogger(ConditionPlayerGrade.class.getName());
|
||||
// conditional values
|
||||
public static final int COND_NO_GRADE = 0x0001;
|
||||
public static final int COND_D_GRADE = 0x0002;
|
||||
public static final int COND_C_GRADE = 0x0004;
|
||||
public static final int COND_B_GRADE = 0x0008;
|
||||
public static final int COND_A_GRADE = 0x0010;
|
||||
public static final int COND_S_GRADE = 0x0020;
|
||||
public static final int COND_S80_GRADE = 0x0040;
|
||||
public static final int COND_S84_GRADE = 0x0080;
|
||||
|
||||
private final int _value;
|
||||
|
||||
/**
|
||||
* Instantiates a new condition player grade.
|
||||
* @param value the value
|
||||
*/
|
||||
public ConditionPlayerGrade(int value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean testImpl(L2Character effector, L2Character effected, Skill skill, L2Item item)
|
||||
{
|
||||
return (effector.getActingPlayer() != null) && (_value == (byte) effector.getActingPlayer().getExpertiseLevel());
|
||||
}
|
||||
}
|
@ -0,0 +1,336 @@
|
||||
/*
|
||||
* 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 java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.interfaces.IIdentifiable;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
/**
|
||||
* A holder representing a craftable recipe based on the former L2RecipeList.<br>
|
||||
* It contains all the recipe data and methods required for crafting this recipe.
|
||||
* @author Nik
|
||||
*/
|
||||
public class RecipeHolder implements IIdentifiable
|
||||
{
|
||||
/** List of materials required to craft this recipe. */
|
||||
private final List<ItemHolder> _materials;
|
||||
|
||||
/** Group of products where a single product will randomly be selected upon crafting. */
|
||||
private final List<ItemChanceHolder> _productGroup;
|
||||
|
||||
private final List<ItemHolder> _npcFee;
|
||||
|
||||
/** Stats and amount required to perform the craft. */
|
||||
private final Map<StatusUpdateType, Double> _statUse;
|
||||
|
||||
private final int _id;
|
||||
private final int _level;
|
||||
private final int _itemId;
|
||||
private final String _name;
|
||||
private final double _successRate;
|
||||
private final boolean _isCommonRecipe;
|
||||
private final double _maxOfferingBonus;
|
||||
private final long _maxOffering;
|
||||
|
||||
public RecipeHolder(StatsSet set, List<ItemHolder> ingredients, List<ItemChanceHolder> productGroup, List<ItemHolder> npcFee, Map<StatusUpdateType, Double> statUse)
|
||||
{
|
||||
_id = set.getInt("id");
|
||||
_level = set.getInt("level");
|
||||
_itemId = set.getInt("itemId");
|
||||
_name = set.getString("name");
|
||||
_successRate = set.getDouble("successRate");
|
||||
_isCommonRecipe = set.getBoolean("isCommonRecipe");
|
||||
_maxOfferingBonus = set.getDouble("maxOfferingBonus", Math.max(0, 100 - _successRate));
|
||||
_maxOffering = set.getLong("maxOffering", 0);
|
||||
|
||||
_materials = Collections.unmodifiableList(ingredients);
|
||||
_productGroup = Collections.unmodifiableList(productGroup);
|
||||
_npcFee = Collections.unmodifiableList(npcFee);
|
||||
_statUse = Collections.unmodifiableMap(statUse);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the recipe id, NOT the recipe's item id
|
||||
*/
|
||||
@Override
|
||||
public int getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the crafting level needed to use this L2RecipeList.
|
||||
*/
|
||||
public int getLevel()
|
||||
{
|
||||
return _level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the recipe's item id.
|
||||
*/
|
||||
public int getItemId()
|
||||
{
|
||||
return _itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the L2RecipeList.
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the crafting success rate when using the L2RecipeList.
|
||||
*/
|
||||
public double getSuccessRate()
|
||||
{
|
||||
return _successRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if this a Dwarven recipe or {@code false} if its a Common recipe
|
||||
*/
|
||||
public boolean isDwarvenRecipe()
|
||||
{
|
||||
return !_isCommonRecipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of materials required to complete the recipe.
|
||||
*/
|
||||
public List<ItemHolder> getMaterials()
|
||||
{
|
||||
return _materials;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the whole group of products from which one random item will result in being crafted.
|
||||
*/
|
||||
public List<ItemChanceHolder> getProductGroup()
|
||||
{
|
||||
return _productGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of items that NPCs take for crafting this recipe.
|
||||
*/
|
||||
public List<ItemHolder> getNpcFee()
|
||||
{
|
||||
return _npcFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the table containing all L2RecipeStatInstance of the statUse parameter of the L2RecipeList.
|
||||
*/
|
||||
public Map<StatusUpdateType, Double> getStatUse()
|
||||
{
|
||||
return _statUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Maximum bonus success rate when maximum offering is reached. Default is the rate needed to reach 100% success rate.
|
||||
*/
|
||||
public double getMaxOfferingBonus()
|
||||
{
|
||||
return _maxOfferingBonus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Maximum amount of items' adena worth offering. {@code 0} if this recipe does not allow offering.
|
||||
*/
|
||||
public long getMaxOffering()
|
||||
{
|
||||
return _maxOffering;
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks a random number then attempts to get a product from the group based on it.
|
||||
* @return {@code ItemChanceHolder} that is the randomly picked product from the group,<br>
|
||||
* or {@code null} if the whole chance sum of the products in the group didn't manage to outnumber the random.
|
||||
*/
|
||||
public ItemChanceHolder getRandomProduct()
|
||||
{
|
||||
double random = Rnd.get(100);
|
||||
for (ItemChanceHolder product : _productGroup)
|
||||
{
|
||||
if (product.getChance() > random)
|
||||
{
|
||||
return product;
|
||||
}
|
||||
|
||||
random -= product.getChance();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean checkNecessaryStats(L2PcInstance player, L2PcInstance manufacturer, boolean sendMessage)
|
||||
{
|
||||
for (Entry<StatusUpdateType, Double> entry : _statUse.entrySet())
|
||||
{
|
||||
final StatusUpdateType stat = entry.getKey();
|
||||
final double requiredAmount = entry.getValue();
|
||||
|
||||
// Less than or equals to because some stats bad interraction - like HP could kill the player if its taken all.
|
||||
if (stat.getValue(manufacturer) <= requiredAmount)
|
||||
{
|
||||
if (sendMessage)
|
||||
{
|
||||
switch (stat)
|
||||
{
|
||||
case CUR_HP:
|
||||
{
|
||||
player.sendPacket(SystemMessageId.NOT_ENOUGH_HP);
|
||||
break;
|
||||
}
|
||||
case CUR_MP:
|
||||
{
|
||||
player.sendPacket(SystemMessageId.NOT_ENOUGH_MP);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
player.sendMessage("You need " + requiredAmount + " " + stat.toString().toLowerCase() + " to perform this craft.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player the player's inventory to check.
|
||||
* @param sendMessage send system messages for item requirements if there is missing ingredient.
|
||||
* @return {@code true} if all necessary ingredients are met, {@code false} if there are missing ingredients.
|
||||
*/
|
||||
public boolean checkNecessaryIngredients(L2PcInstance player, boolean sendMessage)
|
||||
{
|
||||
for (ItemHolder ingredient : getMaterials())
|
||||
{
|
||||
final long count = player.getInventory().getInventoryItemCount(ingredient.getId(), -1);
|
||||
if (count < ingredient.getCount())
|
||||
{
|
||||
if (sendMessage)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_MORE_S1_S);
|
||||
sm.addItemName(ingredient.getId());
|
||||
sm.addLong(ingredient.getCount() - count);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player the player requesting the craft.
|
||||
* @param manufacturer the player doing the craft (either the same player or manufacture shop).
|
||||
* @param success {@code true} to give the product item to the player, {@code false} otherwise.
|
||||
* @param craftingCritical {@code true} to give double of the product (if success), {@code false} otherwise.
|
||||
* @param sendMessage send system messages of the process.
|
||||
* @return {@code ItemHolder} of the randomly created product (even if its failing craft), {@code null} if the item creation was not performed due to failed checks.
|
||||
*/
|
||||
public ItemHolder doCraft(L2PcInstance player, L2PcInstance manufacturer, boolean success, boolean craftingCritical, boolean sendMessage)
|
||||
{
|
||||
if (!checkNecessaryStats(player, manufacturer, sendMessage))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!checkNecessaryIngredients(player, sendMessage))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Take necessary stats.
|
||||
for (Entry<StatusUpdateType, Double> entry : _statUse.entrySet())
|
||||
{
|
||||
final StatusUpdateType stat = entry.getKey();
|
||||
final double requiredAmount = entry.getValue();
|
||||
|
||||
switch (stat)
|
||||
{
|
||||
case CUR_HP:
|
||||
{
|
||||
manufacturer.reduceCurrentHp(requiredAmount, manufacturer, null);
|
||||
break;
|
||||
}
|
||||
case CUR_MP:
|
||||
{
|
||||
manufacturer.reduceCurrentMp(requiredAmount);
|
||||
break;
|
||||
}
|
||||
case CUR_CP:
|
||||
{
|
||||
manufacturer.getStatus().reduceCp((int) requiredAmount);
|
||||
break;
|
||||
}
|
||||
case EXP:
|
||||
{
|
||||
manufacturer.getStat().removeExp((long) requiredAmount);
|
||||
break;
|
||||
}
|
||||
case REPUTATION:
|
||||
{
|
||||
manufacturer.setReputation((int) (manufacturer.getReputation() - requiredAmount));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Take necessary ingredients. If there was problem destroying item, return null to insicate that process didn't go well.
|
||||
if (getMaterials().stream().anyMatch(i -> !player.destroyItemByItemId("Recipe " + getId(), i.getId(), i.getCount(), manufacturer, sendMessage)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if success. Luck triggers no matter the success rate - even with 100% craft. Luck chance is taken from your stat and not manufacturer's stat.
|
||||
final ItemHolder result = getRandomProduct();
|
||||
if (success)
|
||||
{
|
||||
player.addItem("Craft", result, manufacturer, true);
|
||||
|
||||
// Award another item if its crafting critical. Double blessed items is very, very rare, but still possible.
|
||||
if (craftingCritical)
|
||||
{
|
||||
player.addItem("CraftCritical", result, manufacturer, true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -401,7 +401,7 @@ public abstract class Inventory extends ItemContainer
|
||||
final L2PcInstance player = (L2PcInstance) inventory.getOwner();
|
||||
|
||||
// Any items equipped that result in expertise penalty do not give any skills at all.
|
||||
if (item.getItem().getCrystalType().getId() > player.getExpertiseLevel())
|
||||
if (item.getItem().getCrystalType().isGreater(player.getExpertiseLevel()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable
|
||||
private int _time;
|
||||
private int _autoDestroyTime;
|
||||
private int _bodyPart;
|
||||
private int _referencePrice;
|
||||
private long _referencePrice;
|
||||
private int _crystalCount;
|
||||
private boolean _sellable;
|
||||
private boolean _dropable;
|
||||
@ -200,7 +200,7 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable
|
||||
_time = set.getInt("time", -1);
|
||||
_autoDestroyTime = set.getInt("auto_destroy_time", -1) * 1000;
|
||||
_bodyPart = ItemTable.SLOTS.get(set.getString("bodypart", "none"));
|
||||
_referencePrice = set.getInt("price", 0);
|
||||
_referencePrice = set.getLong("price", 0);
|
||||
_crystalType = set.getEnum("crystal_type", CrystalType.class, CrystalType.NONE);
|
||||
_crystalCount = set.getInt("crystal_count", 0);
|
||||
|
||||
@ -538,7 +538,7 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable
|
||||
/**
|
||||
* @return the price of reference of the item.
|
||||
*/
|
||||
public final int getReferencePrice()
|
||||
public final long getReferencePrice()
|
||||
{
|
||||
return _referencePrice;
|
||||
}
|
||||
|
@ -731,7 +731,7 @@ public final class L2ItemInstance extends L2Object
|
||||
/**
|
||||
* @return the reference price of the item.
|
||||
*/
|
||||
public int getReferencePrice()
|
||||
public long getReferencePrice()
|
||||
{
|
||||
return _item.getReferencePrice();
|
||||
}
|
||||
|
@ -35,14 +35,14 @@ public enum CrystalType
|
||||
R99(10, 17371, 30, 500),
|
||||
EVENT(11, 0, 0, 0);
|
||||
|
||||
private final int _id;
|
||||
private final int _level;
|
||||
private final int _crystalId;
|
||||
private final int _crystalEnchantBonusArmor;
|
||||
private final int _crystalEnchantBonusWeapon;
|
||||
|
||||
CrystalType(int id, int crystalId, int crystalEnchantBonusArmor, int crystalEnchantBonusWeapon)
|
||||
CrystalType(int level, int crystalId, int crystalEnchantBonusArmor, int crystalEnchantBonusWeapon)
|
||||
{
|
||||
_id = id;
|
||||
_level = level;
|
||||
_crystalId = crystalId;
|
||||
_crystalEnchantBonusArmor = crystalEnchantBonusArmor;
|
||||
_crystalEnchantBonusWeapon = crystalEnchantBonusWeapon;
|
||||
@ -52,9 +52,9 @@ public enum CrystalType
|
||||
* Gets the crystal type ID.
|
||||
* @return the crystal type ID
|
||||
*/
|
||||
public int getId()
|
||||
public int getLevel()
|
||||
{
|
||||
return _id;
|
||||
return _level;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,11 +78,41 @@ public enum CrystalType
|
||||
|
||||
public boolean isGreater(CrystalType crystalType)
|
||||
{
|
||||
return getId() > crystalType.getId();
|
||||
return getLevel() > crystalType.getLevel();
|
||||
}
|
||||
|
||||
public boolean isLesser(CrystalType crystalType)
|
||||
{
|
||||
return getId() < crystalType.getId();
|
||||
return getLevel() < crystalType.getLevel();
|
||||
}
|
||||
|
||||
public CrystalType plusLevel(int level)
|
||||
{
|
||||
level += getLevel();
|
||||
|
||||
if (level >= CrystalType.R99.getLevel())
|
||||
{
|
||||
return CrystalType.R99;
|
||||
}
|
||||
|
||||
if (level <= CrystalType.NONE.getLevel())
|
||||
{
|
||||
return CrystalType.NONE;
|
||||
}
|
||||
|
||||
return getByLevel(level);
|
||||
}
|
||||
|
||||
public static CrystalType getByLevel(int level)
|
||||
{
|
||||
for (CrystalType crystalType : values())
|
||||
{
|
||||
if (crystalType.getLevel() == level)
|
||||
{
|
||||
return crystalType;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -266,6 +266,7 @@ public enum Stats
|
||||
// Which base stat ordinal should alter skill critical formula.
|
||||
STAT_BONUS_SKILL_CRITICAL("statSkillCritical"),
|
||||
STAT_BONUS_SPEED("statSpeed"),
|
||||
CRAFTING_CRITICAL("craftingCritical"),
|
||||
SHOTS_BONUS("shotBonus", new ShotsBonusFinalizer());
|
||||
|
||||
static final Logger LOGGER = Logger.getLogger(Stats.class.getName());
|
||||
|
@ -790,7 +790,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
default:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isInCraftMode();
|
||||
canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isCrafting();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,11 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeList;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList;
|
||||
|
||||
public final class RequestRecipeBookDestroy implements IClientIncomingPacket
|
||||
@ -48,23 +50,24 @@ public final class RequestRecipeBookDestroy implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
final L2RecipeList rp = RecipeData.getInstance().getRecipeList(_recipeID);
|
||||
if (rp == null)
|
||||
if ((activeChar.getPrivateStoreType() == PrivateStoreType.MANUFACTURE) || activeChar.isCrafting())
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING);
|
||||
return;
|
||||
}
|
||||
|
||||
final RecipeHolder rp = RecipeData.getInstance().getRecipe(_recipeID);
|
||||
if (rp == null)
|
||||
{
|
||||
client.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the recipe from the list.
|
||||
activeChar.unregisterRecipeList(_recipeID);
|
||||
|
||||
final RecipeBookItemList response = new RecipeBookItemList(rp.isDwarvenRecipe(), activeChar.getMaxMp());
|
||||
if (rp.isDwarvenRecipe())
|
||||
{
|
||||
response.addRecipes(activeChar.getDwarvenRecipeBook());
|
||||
}
|
||||
else
|
||||
{
|
||||
response.addRecipes(activeChar.getCommonRecipeBook());
|
||||
}
|
||||
|
||||
// Send the new recipe book.
|
||||
final RecipeBookItemList response = new RecipeBookItemList(activeChar, rp.isDwarvenRecipe());
|
||||
activeChar.sendPacket(response);
|
||||
}
|
||||
}
|
@ -17,10 +17,11 @@
|
||||
package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.RecipeController;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList;
|
||||
|
||||
public final class RequestRecipeBookOpen implements IClientIncomingPacket
|
||||
{
|
||||
@ -48,12 +49,19 @@ public final class RequestRecipeBookOpen implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeChar.getActiveRequester() != null)
|
||||
if (activeChar.getPrivateStoreType() == PrivateStoreType.MANUFACTURE)
|
||||
{
|
||||
activeChar.sendMessage("You may not alter your recipe book while trading.");
|
||||
client.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING);
|
||||
return;
|
||||
}
|
||||
|
||||
RecipeController.getInstance().requestBookOpen(activeChar, _isDwarvenCraft);
|
||||
if (activeChar.isProcessingTransaction())
|
||||
{
|
||||
client.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE);
|
||||
return;
|
||||
}
|
||||
|
||||
final RecipeBookItemList response = new RecipeBookItemList(activeChar, _isDwarvenCraft);
|
||||
activeChar.sendPacket(response);
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,11 @@
|
||||
package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeItemMakeInfo;
|
||||
|
||||
public final class RequestRecipeItemMakeInfo implements IClientIncomingPacket
|
||||
@ -41,6 +44,13 @@ public final class RequestRecipeItemMakeInfo implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
client.sendPacket(new RecipeItemMakeInfo(_id, player));
|
||||
final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_id);
|
||||
if (recipe == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT);
|
||||
return;
|
||||
}
|
||||
|
||||
client.sendPacket(new RecipeItemMakeInfo(_id, player, recipe.getMaxOffering()));
|
||||
}
|
||||
}
|
||||
|
@ -16,23 +16,45 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.RecipeController;
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeItemMakeInfo;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @author Nik
|
||||
*/
|
||||
public final class RequestRecipeItemMakeSelf implements IClientIncomingPacket
|
||||
{
|
||||
private int _id;
|
||||
private ItemHolder[] _offeredItems;
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
{
|
||||
_id = packet.readD();
|
||||
|
||||
final int offeringsCount = packet.readD();
|
||||
if (offeringsCount > 0)
|
||||
{
|
||||
_offeredItems = new ItemHolder[offeringsCount];
|
||||
for (int i = 0; i < offeringsCount; i++)
|
||||
{
|
||||
final int objectId = packet.readD();
|
||||
final long count = packet.readQ();
|
||||
_offeredItems[i] = new ItemHolder(objectId, count);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -45,23 +67,122 @@ public final class RequestRecipeItemMakeSelf implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Config.IS_CRAFTING_ENABLED)
|
||||
{
|
||||
activeChar.sendMessage("Item creation is currently disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!client.getFloodProtectors().getManufacture().tryPerformAction("RecipeMakeSelf"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeChar.getPrivateStoreType() != PrivateStoreType.NONE)
|
||||
if (activeChar.isCastingNow())
|
||||
{
|
||||
activeChar.sendMessage("You cannot create items while trading.");
|
||||
activeChar.sendPacket(SystemMessageId.YOUR_RECIPE_BOOK_MAY_NOT_BE_ACCESSED_WHILE_USING_A_SKILL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeChar.isInCraftMode())
|
||||
if (activeChar.getPrivateStoreType() == PrivateStoreType.MANUFACTURE)
|
||||
{
|
||||
activeChar.sendMessage("You are currently in Craft Mode.");
|
||||
activeChar.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING);
|
||||
return;
|
||||
}
|
||||
|
||||
RecipeController.getInstance().requestMakeItem(activeChar, _id);
|
||||
if (activeChar.isProcessingTransaction())
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Check if its a retail-like check.
|
||||
if (activeChar.isAlikeDead())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// On retail if player is requesting trade, it is instantly canceled.
|
||||
activeChar.cancelActiveTrade();
|
||||
|
||||
final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_id);
|
||||
if (recipe == null)
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!activeChar.hasRecipeList(recipe.getId()))
|
||||
{
|
||||
Util.handleIllegalPlayerAction(activeChar, "Warning!! Character " + activeChar.getName() + " of account " + activeChar.getAccountName() + " sent a false recipe id.", Config.DEFAULT_PUNISH);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if stats or ingredients are met.
|
||||
if (!recipe.checkNecessaryStats(activeChar, activeChar, true) || !recipe.checkNecessaryIngredients(activeChar, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if all offerings are legit.
|
||||
if ((_offeredItems != null) && (recipe.getMaxOffering() > 0) && (recipe.getMaxOfferingBonus() > 0))
|
||||
{
|
||||
for (ItemHolder offer : _offeredItems)
|
||||
{
|
||||
final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(offer.getId());
|
||||
if ((item == null) || (item.getCount() < offer.getCount()) || !item.isDestroyable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (activeChar.isCrafting())
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.CURRENTLY_CRAFTING_AN_ITEM_PLEASE_WAIT);
|
||||
return;
|
||||
}
|
||||
|
||||
activeChar.setIsCrafting(true);
|
||||
|
||||
// Take offerings to increase chance
|
||||
double offeringBonus = 0;
|
||||
if ((_offeredItems != null) && (recipe.getMaxOffering() > 0) && (recipe.getMaxOfferingBonus() > 0))
|
||||
{
|
||||
long offeredAdenaWorth = 0;
|
||||
for (ItemHolder offer : _offeredItems)
|
||||
{
|
||||
final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(offer.getId());
|
||||
if (activeChar.destroyItem("CraftOffering", item, offer.getCount(), null, true))
|
||||
{
|
||||
offeredAdenaWorth += (item.getItem().getReferencePrice() * offer.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
offeringBonus = Math.min((offeredAdenaWorth / recipe.getMaxOffering()) * recipe.getMaxOfferingBonus(), recipe.getMaxOfferingBonus());
|
||||
}
|
||||
|
||||
final boolean success = activeChar.tryLuck() || ((recipe.getSuccessRate() + offeringBonus) > Rnd.get(100));
|
||||
final boolean craftingCritical = success && (activeChar.getStat().getValue(Stats.CRAFTING_CRITICAL) > Rnd.get(100));
|
||||
|
||||
if (success) // Successful craft.
|
||||
{
|
||||
if (craftingCritical)
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.CRAFTING_CRITICAL);
|
||||
}
|
||||
}
|
||||
else // Failed craft.
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.YOU_FAILED_AT_MIXING_THE_ITEM);
|
||||
}
|
||||
|
||||
// Perform the crafting: take the items and give reward if success.
|
||||
recipe.doCraft(activeChar, activeChar, success, craftingCritical, true);
|
||||
|
||||
// Send craft window. Must be sent after crafting so it properly counts the items.
|
||||
activeChar.sendPacket(new RecipeItemMakeInfo(recipe.getId(), activeChar, success, recipe.getMaxOffering()));
|
||||
|
||||
activeChar.setIsCrafting(false);
|
||||
}
|
||||
}
|
||||
|
@ -18,16 +18,17 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import static com.l2jmobius.gameserver.model.itemcontainer.Inventory.MAX_ADENA;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.L2ManufactureItem;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeList;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
@ -44,28 +45,28 @@ public final class RequestRecipeShopListSet implements IClientIncomingPacket
|
||||
{
|
||||
private static final int BATCH_LENGTH = 12;
|
||||
|
||||
private L2ManufactureItem[] _items = null;
|
||||
private Map<Integer, Long> _manufactureRecipes = null;
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
{
|
||||
final int count = packet.readD();
|
||||
int count = packet.readD();
|
||||
if ((count <= 0) || (count > Config.MAX_ITEM_IN_PACKET) || ((count * BATCH_LENGTH) != packet.getReadableBytes()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_items = new L2ManufactureItem[count];
|
||||
_manufactureRecipes = new HashMap<>(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
final int id = packet.readD();
|
||||
final long cost = packet.readQ();
|
||||
int id = packet.readD();
|
||||
long cost = packet.readQ();
|
||||
if (cost < 0)
|
||||
{
|
||||
_items = null;
|
||||
_manufactureRecipes = null;
|
||||
return false;
|
||||
}
|
||||
_items[i] = new L2ManufactureItem(id, cost);
|
||||
_manufactureRecipes.put(id, cost);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -79,13 +80,26 @@ public final class RequestRecipeShopListSet implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (_items == null)
|
||||
if (_manufactureRecipes == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.ITEMS_ARE_NOT_AVAILABLE_FOR_A_PRIVATE_STORE_OR_PRIVATE_WORKSHOP);
|
||||
player.setPrivateStoreType(PrivateStoreType.NONE);
|
||||
player.broadcastUserInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isCastingNow())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.A_PRIVATE_STORE_MAY_NOT_BE_OPENED_WHILE_USING_A_SKILL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isCrafting())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.CURRENTLY_CRAFTING_AN_ITEM_PLEASE_WAIT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player) || player.isInDuel())
|
||||
{
|
||||
client.sendPacket(SystemMessageId.WHILE_YOU_ARE_ENGAGED_IN_COMBAT_YOU_CANNOT_OPERATE_A_PRIVATE_STORE_OR_PRIVATE_WORKSHOP);
|
||||
@ -100,29 +114,36 @@ public final class RequestRecipeShopListSet implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
final List<L2RecipeList> dwarfRecipes = Arrays.asList(player.getDwarvenRecipeBook());
|
||||
final List<L2RecipeList> commonRecipes = Arrays.asList(player.getCommonRecipeBook());
|
||||
|
||||
player.getManufactureItems().clear();
|
||||
|
||||
for (L2ManufactureItem i : _items)
|
||||
for (Entry<Integer, Long> item : _manufactureRecipes.entrySet())
|
||||
{
|
||||
final L2RecipeList list = RecipeData.getInstance().getRecipeList(i.getRecipeId());
|
||||
if (!dwarfRecipes.contains(list) && !commonRecipes.contains(list))
|
||||
final int recipeId = item.getKey();
|
||||
final long recipeCost = item.getValue();
|
||||
final RecipeHolder recipe = RecipeData.getInstance().getRecipe(recipeId);
|
||||
if (recipe == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT);
|
||||
return;
|
||||
}
|
||||
if (ItemTable.getInstance().getTemplate(recipe.getItemId()).isQuestItem())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.QUEST_RECIPES_CAN_NOT_BE_REGISTERED);
|
||||
return;
|
||||
}
|
||||
if (!player.hasRecipeList(recipe.getId()))
|
||||
{
|
||||
Util.handleIllegalPlayerAction(player, "Warning!! Player " + player.getName() + " of account " + player.getAccountName() + " tried to set recipe which he dont have.", Config.DEFAULT_PUNISH);
|
||||
return;
|
||||
}
|
||||
|
||||
if (i.getCost() > MAX_ADENA)
|
||||
if (recipeCost > MAX_ADENA)
|
||||
{
|
||||
Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " tried to set price more than " + MAX_ADENA + " adena in Private Manufacture.", Config.DEFAULT_PUNISH);
|
||||
Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " tried to set price of " + recipeCost + " adena in Private Manufacture.", Config.DEFAULT_PUNISH);
|
||||
return;
|
||||
}
|
||||
|
||||
player.getManufactureItems().put(i.getRecipeId(), i);
|
||||
}
|
||||
|
||||
player.setManufactureItems(_manufactureRecipes);
|
||||
|
||||
player.setStoreName(!player.hasManufactureShop() ? "" : player.getStoreName());
|
||||
player.setPrivateStoreType(PrivateStoreType.MANUFACTURE);
|
||||
player.sitDown();
|
||||
|
@ -17,10 +17,13 @@
|
||||
package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeShopItemInfo;
|
||||
|
||||
/**
|
||||
@ -49,12 +52,25 @@ public final class RequestRecipeShopMakeInfo implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance shop = L2World.getInstance().getPlayer(_playerObjectId);
|
||||
if ((shop == null) || (shop.getPrivateStoreType() != PrivateStoreType.MANUFACTURE))
|
||||
final L2PcInstance manufacturer = L2World.getInstance().getPlayer(_playerObjectId);
|
||||
if ((manufacturer == null) || (manufacturer.getPrivateStoreType() != PrivateStoreType.MANUFACTURE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.sendPacket(new RecipeShopItemInfo(shop, _recipeId));
|
||||
final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_recipeId);
|
||||
if (recipe == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT);
|
||||
return;
|
||||
}
|
||||
|
||||
final Long manufactureRecipeCost = manufacturer.getManufactureItems().get(_recipeId);
|
||||
if (manufactureRecipeCost == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.sendPacket(new RecipeShopItemInfo(manufacturer, _recipeId, manufactureRecipeCost, recipe.getMaxOffering()));
|
||||
}
|
||||
}
|
||||
|
@ -16,30 +16,53 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.RecipeController;
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeShopItemInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* It appears you are able to successfully create from manufacture store while casting, while in manufacture store and within 250 range. So basic checks <br>
|
||||
* from your own recipe list crafting are skipped. With the exception of trading, if you request trade, it is cancelled, if you are already trading, you get message.
|
||||
* @author Nik
|
||||
*/
|
||||
public final class RequestRecipeShopMakeItem implements IClientIncomingPacket
|
||||
{
|
||||
private int _id;
|
||||
private int _objectId;
|
||||
private int _recipeId;
|
||||
@SuppressWarnings("unused")
|
||||
private long _unknown;
|
||||
private long _manufacturePrice;
|
||||
private ItemHolder[] _offeredItems;
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
{
|
||||
_id = packet.readD();
|
||||
_objectId = packet.readD();
|
||||
_recipeId = packet.readD();
|
||||
_unknown = packet.readQ();
|
||||
_manufacturePrice = packet.readQ();
|
||||
|
||||
final int offeringsCount = packet.readD();
|
||||
if (offeringsCount > 0)
|
||||
{
|
||||
_offeredItems = new ItemHolder[offeringsCount];
|
||||
for (int i = 0; i < offeringsCount; i++)
|
||||
{
|
||||
final int objectId = packet.readD();
|
||||
final long count = packet.readQ();
|
||||
_offeredItems[i] = new ItemHolder(objectId, count);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -52,41 +75,197 @@ public final class RequestRecipeShopMakeItem implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Config.IS_CRAFTING_ENABLED)
|
||||
{
|
||||
activeChar.sendMessage("Item creation is currently disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!client.getFloodProtectors().getManufacture().tryPerformAction("RecipeShopMake"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance manufacturer = L2World.getInstance().getPlayer(_id);
|
||||
final L2PcInstance manufacturer = L2World.getInstance().getPlayer(_objectId);
|
||||
if (manufacturer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (manufacturer.getInstanceWorld() != activeChar.getInstanceWorld())
|
||||
if ((manufacturer.getInstanceWorld() != activeChar.getInstanceWorld()) || (activeChar.calculateDistance(manufacturer, false, false) > 250))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeChar.getPrivateStoreType() != PrivateStoreType.NONE)
|
||||
{
|
||||
activeChar.sendMessage("You cannot create items while trading.");
|
||||
return;
|
||||
}
|
||||
if (manufacturer.getPrivateStoreType() != PrivateStoreType.MANUFACTURE)
|
||||
{
|
||||
// activeChar.sendMessage("You cannot create items while trading.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeChar.isInCraftMode() || manufacturer.isInCraftMode())
|
||||
if (activeChar.isProcessingTransaction() || manufacturer.isProcessingTransaction())
|
||||
{
|
||||
activeChar.sendMessage("You are currently in Craft Mode.");
|
||||
activeChar.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE);
|
||||
return;
|
||||
}
|
||||
if (Util.checkIfInRange(150, activeChar, manufacturer, true))
|
||||
|
||||
// TODO: Check if its a retail-like check.
|
||||
if (activeChar.isAlikeDead() || manufacturer.isAlikeDead())
|
||||
{
|
||||
RecipeController.getInstance().requestManufactureItem(manufacturer, _recipeId, activeChar);
|
||||
return;
|
||||
}
|
||||
|
||||
// On retail if player is requesting trade, it is instantly canceled.
|
||||
activeChar.cancelActiveTrade();
|
||||
|
||||
final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_recipeId);
|
||||
if (recipe == null)
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!manufacturer.hasRecipeList(recipe.getId()))
|
||||
{
|
||||
Util.handleIllegalPlayerAction(activeChar, "Warning!! Character " + activeChar.getName() + " of account " + activeChar.getAccountName() + " sent a false recipe id.", Config.DEFAULT_PUNISH);
|
||||
return;
|
||||
}
|
||||
|
||||
final Long manufactureRecipeCost = manufacturer.getManufactureItems().get(_recipeId);
|
||||
if (manufactureRecipeCost == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the price is the same as requested price.
|
||||
if (_manufacturePrice != manufactureRecipeCost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if player can pay.
|
||||
if (activeChar.getAdena() < manufactureRecipeCost)
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if stats or ingredients are met.
|
||||
if (!recipe.checkNecessaryStats(activeChar, manufacturer, true) || !recipe.checkNecessaryIngredients(activeChar, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if all offerings are legit.
|
||||
if ((_offeredItems != null) && (recipe.getMaxOffering() > 0) && (recipe.getMaxOfferingBonus() > 0))
|
||||
{
|
||||
for (ItemHolder offer : _offeredItems)
|
||||
{
|
||||
final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(offer.getId());
|
||||
if ((item == null) || (item.getCount() < offer.getCount()) || !item.isDestroyable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (manufacturer.isCrafting())
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.CURRENTLY_CRAFTING_AN_ITEM_PLEASE_WAIT);
|
||||
return;
|
||||
}
|
||||
|
||||
manufacturer.setIsCrafting(true);
|
||||
|
||||
// First you must pay for the manufacturing service of the other player.
|
||||
if (manufactureRecipeCost > 0)
|
||||
{
|
||||
// Attempt to pay the required manufacturing price by the manufacturer.
|
||||
L2ItemInstance paidAdena = activeChar.transferItem("PayManufacture", activeChar.getInventory().getAdenaInstance().getObjectId(), manufactureRecipeCost, manufacturer.getInventory(), manufacturer);
|
||||
|
||||
if (paidAdena == null)
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Take offerings to increase chance
|
||||
double offeringBonus = 0;
|
||||
if ((_offeredItems != null) && (recipe.getMaxOffering() > 0) && (recipe.getMaxOfferingBonus() > 0))
|
||||
{
|
||||
long offeredAdenaWorth = 0;
|
||||
for (ItemHolder offer : _offeredItems)
|
||||
{
|
||||
final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(offer.getId());
|
||||
if (activeChar.destroyItem("CraftOffering", item, offer.getCount(), manufacturer, true))
|
||||
{
|
||||
offeredAdenaWorth += (item.getItem().getReferencePrice() * offer.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
offeringBonus = Math.min((offeredAdenaWorth / recipe.getMaxOffering()) * recipe.getMaxOfferingBonus(), recipe.getMaxOfferingBonus());
|
||||
}
|
||||
|
||||
final boolean success = activeChar.tryLuck() || ((recipe.getSuccessRate() + offeringBonus) > Rnd.get(100));
|
||||
final boolean craftingCritical = success && (activeChar.getStat().getValue(Stats.CRAFTING_CRITICAL) > Rnd.get(100));
|
||||
|
||||
final ItemHolder craftedItem = recipe.doCraft(activeChar, manufacturer, success, craftingCritical, true);
|
||||
if (success)
|
||||
{
|
||||
if (craftingCritical)
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.CRAFTING_CRITICAL);
|
||||
}
|
||||
if (craftedItem.getCount() > 1)
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S3_S2_S_HAVE_BEEN_CREATED_FOR_C1_AT_THE_PRICE_OF_S4_ADENA);
|
||||
sm.addString(activeChar.getName());
|
||||
sm.addInt((int) craftedItem.getCount());
|
||||
sm.addItemName(craftedItem.getId());
|
||||
sm.addLong(manufactureRecipeCost);
|
||||
manufacturer.sendPacket(sm);
|
||||
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_CREATED_S3_S2_S_AT_THE_PRICE_OF_S4_ADENA);
|
||||
sm.addString(manufacturer.getName());
|
||||
sm.addInt((int) craftedItem.getCount());
|
||||
sm.addItemName(craftedItem.getId());
|
||||
sm.addLong(manufactureRecipeCost);
|
||||
activeChar.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S2_HAS_BEEN_CREATED_FOR_C1_AFTER_THE_PAYMENT_OF_S3_ADENA_WAS_RECEIVED);
|
||||
sm.addString(activeChar.getName());
|
||||
sm.addItemName(craftedItem.getId());
|
||||
sm.addLong(manufactureRecipeCost);
|
||||
manufacturer.sendPacket(sm);
|
||||
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_CREATED_S2_AFTER_RECEIVING_S3_ADENA);
|
||||
sm.addString(manufacturer.getName());
|
||||
sm.addItemName(craftedItem.getId());
|
||||
sm.addLong(manufactureRecipeCost);
|
||||
activeChar.sendPacket(sm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_FAILED_TO_CREATE_S2_FOR_C1_AT_THE_PRICE_OF_S3_ADENA);
|
||||
sm.addString(activeChar.getName());
|
||||
sm.addItemName(craftedItem.getId());
|
||||
sm.addLong(manufactureRecipeCost);
|
||||
manufacturer.sendPacket(sm);
|
||||
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_FAILED_TO_CREATE_S2_AT_THE_PRICE_OF_S3_ADENA);
|
||||
sm.addString(manufacturer.getName());
|
||||
sm.addItemName(craftedItem.getId());
|
||||
sm.addLong(manufactureRecipeCost);
|
||||
activeChar.sendPacket(sm);
|
||||
}
|
||||
|
||||
// Show manufacturing window.
|
||||
activeChar.sendPacket(new RecipeShopItemInfo(manufacturer, recipe.getId(), success, _manufacturePrice, recipe.getMaxOffering()));
|
||||
|
||||
manufacturer.setIsCrafting(false);
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,12 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeShopManageList;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
|
||||
public final class RequestRecipeShopManageList implements IClientIncomingPacket
|
||||
{
|
||||
@ -40,6 +43,38 @@ public final class RequestRecipeShopManageList implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getCommonRecipeBook().isEmpty() && player.getDwarvenRecipeBook().isEmpty())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.NO_RECIPES_HAVE_BEEN_REGISTERED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isCastingNow())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.A_PRIVATE_STORE_MAY_NOT_BE_OPENED_WHILE_USING_A_SKILL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isCrafting())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.CURRENTLY_CRAFTING_AN_ITEM_PLEASE_WAIT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player) || player.isInDuel())
|
||||
{
|
||||
client.sendPacket(SystemMessageId.WHILE_YOU_ARE_ENGAGED_IN_COMBAT_YOU_CANNOT_OPERATE_A_PRIVATE_STORE_OR_PRIVATE_WORKSHOP);
|
||||
client.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isInsideZone(ZoneId.NO_STORE))
|
||||
{
|
||||
client.sendPacket(SystemMessageId.YOU_CANNOT_OPEN_A_PRIVATE_WORKSHOP_HERE);
|
||||
client.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
// Player shouldn't be able to set stores if he/she is alike dead (dead or fake death)
|
||||
if (player.isAlikeDead())
|
||||
{
|
||||
|
@ -42,7 +42,14 @@ public final class RequestRecipeShopManagePrev implements IClientIncomingPacket
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (player.isAlikeDead() || (player.getTarget() == null) || !player.getTarget().isPlayer())
|
||||
|
||||
if (player.isAlikeDead() || (player.getTarget() == null) || !player.getTarget().isPlayer())
|
||||
{
|
||||
client.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.calculateDistance(player.getTarget(), false, false) > 250)
|
||||
{
|
||||
client.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
|
@ -120,7 +120,7 @@ public class RequestAlchemyTryMixCube implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
final int price = itemInstance.getReferencePrice();
|
||||
final long price = itemInstance.getReferencePrice();
|
||||
if (itemInstance.getReferencePrice() == 0)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THIS_ITEM_CANNOT_BE_COMBINED);
|
||||
|
@ -59,7 +59,7 @@ public class RequestExTryToPutShapeShiftingEnchantSupportItem implements IClient
|
||||
|
||||
final ShapeShiftingItemRequest request = player.getRequest(ShapeShiftingItemRequest.class);
|
||||
|
||||
if (player.isInStoreMode() || player.isInCraftMode() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null))
|
||||
if (player.isInStoreMode() || player.isCrafting() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null))
|
||||
{
|
||||
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THIS_SYSTEM_DURING_TRADING_PRIVATE_STORE_AND_WORKSHOP_SETUP);
|
||||
return;
|
||||
|
@ -54,7 +54,7 @@ public class RequestExTryToPutShapeShiftingTargetItem implements IClientIncoming
|
||||
|
||||
final ShapeShiftingItemRequest request = player.getRequest(ShapeShiftingItemRequest.class);
|
||||
|
||||
if (player.isInStoreMode() || player.isInCraftMode() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null))
|
||||
if (player.isInStoreMode() || player.isCrafting() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null))
|
||||
{
|
||||
client.sendPacket(ExPutShapeShiftingTargetItemResult.FAILED);
|
||||
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THIS_SYSTEM_DURING_TRADING_PRIVATE_STORE_AND_WORKSHOP_SETUP);
|
||||
|
@ -62,7 +62,7 @@ public class RequestShapeShiftingItem implements IClientIncomingPacket
|
||||
|
||||
final ShapeShiftingItemRequest request = player.getRequest(ShapeShiftingItemRequest.class);
|
||||
|
||||
if (player.isInStoreMode() || player.isInCraftMode() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null))
|
||||
if (player.isInStoreMode() || player.isCrafting() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null))
|
||||
{
|
||||
client.sendPacket(ExShapeShiftingResult.CLOSE);
|
||||
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THIS_SYSTEM_DURING_TRADING_PRIVATE_STORE_AND_WORKSHOP_SETUP);
|
||||
|
@ -77,7 +77,7 @@ public class ExShowCropSetting implements IClientOutgoingPacket
|
||||
packet.writeD(s.getCropLimit()); // next sale limit
|
||||
packet.writeD(0); // ???
|
||||
packet.writeD(s.getCropMinPrice()); // min crop price
|
||||
packet.writeD(s.getCropMaxPrice()); // max crop price
|
||||
packet.writeD((int) s.getCropMaxPrice()); // max crop price
|
||||
// Current period
|
||||
if (_current.containsKey(s.getCropId()))
|
||||
{
|
||||
|
@ -48,8 +48,8 @@ public final class ExShowManorDefaultInfo implements IClientOutgoingPacket
|
||||
{
|
||||
packet.writeD(crop.getCropId()); // crop Id
|
||||
packet.writeD(crop.getLevel()); // level
|
||||
packet.writeD(crop.getSeedReferencePrice()); // seed price
|
||||
packet.writeD(crop.getCropReferencePrice()); // crop price
|
||||
packet.writeD((int) crop.getSeedReferencePrice()); // seed price
|
||||
packet.writeD((int) crop.getCropReferencePrice()); // crop price
|
||||
packet.writeC(1); // Reward 1 type
|
||||
packet.writeD(crop.getReward(1)); // Reward 1 itemId
|
||||
packet.writeC(1); // Reward 2 type
|
||||
|
@ -75,9 +75,9 @@ public class ExShowSeedSetting implements IClientOutgoingPacket
|
||||
packet.writeC(1);
|
||||
packet.writeD(s.getReward(2)); // reward 2 id
|
||||
packet.writeD(s.getSeedLimit()); // next sale limit
|
||||
packet.writeD(s.getSeedReferencePrice()); // price for castle to produce 1
|
||||
packet.writeD(s.getSeedMinPrice()); // min seed price
|
||||
packet.writeD(s.getSeedMaxPrice()); // max seed price
|
||||
packet.writeD((int) s.getSeedReferencePrice()); // price for castle to produce 1
|
||||
packet.writeD((int) s.getSeedMinPrice()); // min seed price
|
||||
packet.writeD((int) s.getSeedMaxPrice()); // max seed price
|
||||
// Current period
|
||||
if (_current.containsKey(s.getSeedId()))
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ public class GMViewCharacterInfo implements IClientOutgoingPacket
|
||||
packet.writeD(_activeChar.getAllyId()); // ally id
|
||||
packet.writeC(_activeChar.getMountType().ordinal()); // mount type
|
||||
packet.writeC(_activeChar.getPrivateStoreType().getId());
|
||||
packet.writeC(_activeChar.hasDwarvenCraft() ? 1 : 0);
|
||||
packet.writeC(_activeChar.getCreateItemLevel() > 0 ? 1 : 0);
|
||||
packet.writeD(_activeChar.getPkKills());
|
||||
packet.writeD(_activeChar.getPvpKills());
|
||||
|
||||
|
@ -16,25 +16,24 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeList;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
public class RecipeBookItemList implements IClientOutgoingPacket
|
||||
{
|
||||
private L2RecipeList[] _recipes;
|
||||
private final Collection<RecipeHolder> _recipes;
|
||||
private final boolean _isDwarvenCraft;
|
||||
private final int _maxMp;
|
||||
|
||||
public RecipeBookItemList(boolean isDwarvenCraft, int maxMp)
|
||||
public RecipeBookItemList(L2PcInstance player, boolean isDwarvenCraft)
|
||||
{
|
||||
_isDwarvenCraft = isDwarvenCraft;
|
||||
_maxMp = maxMp;
|
||||
}
|
||||
|
||||
public void addRecipes(L2RecipeList[] recipeBook)
|
||||
{
|
||||
_recipes = recipeBook;
|
||||
_maxMp = player.getMaxMp();
|
||||
_recipes = (isDwarvenCraft ? player.getDwarvenRecipeBook() : player.getCommonRecipeBook());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -51,11 +50,12 @@ public class RecipeBookItemList implements IClientOutgoingPacket
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeD(_recipes.length); // number of items in recipe book
|
||||
for (int i = 0; i < _recipes.length; i++)
|
||||
packet.writeD(_recipes.size()); // number of items in recipe book
|
||||
int i = 1;
|
||||
for (RecipeHolder recipe : _recipes)
|
||||
{
|
||||
packet.writeD(_recipes[i].getId());
|
||||
packet.writeD(i + 1);
|
||||
packet.writeD(recipe.getId());
|
||||
packet.writeD(i++);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -18,34 +18,53 @@ package com.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeList;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
public class RecipeItemMakeInfo implements IClientOutgoingPacket
|
||||
{
|
||||
private final int _id;
|
||||
private final L2PcInstance _activeChar;
|
||||
private final boolean _success;
|
||||
private final Boolean _success;
|
||||
private final long _offeringMaximumAdena;
|
||||
|
||||
public RecipeItemMakeInfo(int id, L2PcInstance player, boolean success, long offeringMaximumAdena)
|
||||
{
|
||||
_id = id;
|
||||
_activeChar = player;
|
||||
_success = success;
|
||||
_offeringMaximumAdena = offeringMaximumAdena;
|
||||
}
|
||||
|
||||
public RecipeItemMakeInfo(int id, L2PcInstance player, boolean success)
|
||||
{
|
||||
_id = id;
|
||||
_activeChar = player;
|
||||
_success = success;
|
||||
_offeringMaximumAdena = 0;
|
||||
}
|
||||
|
||||
public RecipeItemMakeInfo(int id, L2PcInstance player, long offeringMaximumAdena)
|
||||
{
|
||||
_id = id;
|
||||
_activeChar = player;
|
||||
_success = null;
|
||||
_offeringMaximumAdena = offeringMaximumAdena;
|
||||
}
|
||||
|
||||
public RecipeItemMakeInfo(int id, L2PcInstance player)
|
||||
{
|
||||
_id = id;
|
||||
_activeChar = player;
|
||||
_success = true;
|
||||
_success = null;
|
||||
_offeringMaximumAdena = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean write(PacketWriter packet)
|
||||
{
|
||||
final L2RecipeList recipe = RecipeData.getInstance().getRecipeList(_id);
|
||||
final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_id);
|
||||
if (recipe != null)
|
||||
{
|
||||
OutgoingPackets.RECIPE_ITEM_MAKE_INFO.writeId(packet);
|
||||
@ -53,9 +72,9 @@ public class RecipeItemMakeInfo implements IClientOutgoingPacket
|
||||
packet.writeD(recipe.isDwarvenRecipe() ? 0 : 1); // 0 = Dwarven - 1 = Common
|
||||
packet.writeD((int) _activeChar.getCurrentMp());
|
||||
packet.writeD(_activeChar.getMaxMp());
|
||||
packet.writeD(_success ? 1 : 0); // item creation success/failed
|
||||
packet.writeC(0x00);
|
||||
packet.writeQ(0x00);
|
||||
packet.writeD(_success == null ? -1 : (_success ? 1 : 0)); // item creation none/success/failed
|
||||
packet.writeC(_offeringMaximumAdena > 0 ? 1 : 0); // Show offering window.
|
||||
packet.writeQ(_offeringMaximumAdena); // Adena worth of items for maximum offering.
|
||||
return true;
|
||||
}
|
||||
_log.info("Character: " + _activeChar + ": Requested unexisting recipe with id = " + _id);
|
||||
|
@ -22,13 +22,28 @@ import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
public class RecipeShopItemInfo implements IClientOutgoingPacket
|
||||
{
|
||||
private final L2PcInstance _player;
|
||||
private final L2PcInstance _manufacturer;
|
||||
private final int _recipeId;
|
||||
private final Boolean _success;
|
||||
private final long _manufacturePrice;
|
||||
private final long _offeringMaximumAdena;
|
||||
|
||||
public RecipeShopItemInfo(L2PcInstance player, int recipeId)
|
||||
public RecipeShopItemInfo(L2PcInstance manufacturer, int recipeId, boolean success, long manufacturePrice, long offeringMaximumAdena)
|
||||
{
|
||||
_player = player;
|
||||
_manufacturer = manufacturer;
|
||||
_recipeId = recipeId;
|
||||
_success = success;
|
||||
_manufacturePrice = manufacturePrice;
|
||||
_offeringMaximumAdena = offeringMaximumAdena;
|
||||
}
|
||||
|
||||
public RecipeShopItemInfo(L2PcInstance manufacturer, int recipeId, long manufacturePrice, long offeringMaximumAdena)
|
||||
{
|
||||
_manufacturer = manufacturer;
|
||||
_recipeId = recipeId;
|
||||
_success = null;
|
||||
_manufacturePrice = manufacturePrice;
|
||||
_offeringMaximumAdena = offeringMaximumAdena;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -36,14 +51,14 @@ public class RecipeShopItemInfo implements IClientOutgoingPacket
|
||||
{
|
||||
OutgoingPackets.RECIPE_SHOP_ITEM_INFO.writeId(packet);
|
||||
|
||||
packet.writeD(_player.getObjectId());
|
||||
packet.writeD(_manufacturer.getObjectId());
|
||||
packet.writeD(_recipeId);
|
||||
packet.writeD((int) _player.getCurrentMp());
|
||||
packet.writeD(_player.getMaxMp());
|
||||
packet.writeD(0xffffffff);
|
||||
packet.writeQ(0x00);
|
||||
packet.writeC(0x00); // Trigger offering window if 1
|
||||
packet.writeQ(0x00);
|
||||
packet.writeD((int) _manufacturer.getCurrentMp());
|
||||
packet.writeD(_manufacturer.getMaxMp());
|
||||
packet.writeD(_success == null ? -1 : (_success ? 1 : 0)); // item creation none/success/failed
|
||||
packet.writeQ(_manufacturePrice);
|
||||
packet.writeC(_offeringMaximumAdena > 0 ? 1 : 0); // Trigger offering window if 1
|
||||
packet.writeQ(_offeringMaximumAdena);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -16,44 +16,39 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.model.L2ManufactureItem;
|
||||
import com.l2jmobius.gameserver.model.L2RecipeList;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.RecipeHolder;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
public class RecipeShopManageList implements IClientOutgoingPacket
|
||||
{
|
||||
private final L2PcInstance _seller;
|
||||
private final boolean _isDwarven;
|
||||
private L2RecipeList[] _recipes;
|
||||
private final Collection<RecipeHolder> _recipes;
|
||||
private List<Entry<Integer, Long>> _manufacture;
|
||||
|
||||
public RecipeShopManageList(L2PcInstance seller, boolean isDwarven)
|
||||
{
|
||||
_seller = seller;
|
||||
_isDwarven = isDwarven;
|
||||
|
||||
if (_isDwarven && _seller.hasDwarvenCraft())
|
||||
{
|
||||
_recipes = _seller.getDwarvenRecipeBook();
|
||||
}
|
||||
else
|
||||
{
|
||||
_recipes = _seller.getCommonRecipeBook();
|
||||
}
|
||||
_recipes = (isDwarven && (_seller.getCreateItemLevel() > 0)) ? _seller.getDwarvenRecipeBook() : _seller.getCommonRecipeBook();
|
||||
|
||||
if (_seller.hasManufactureShop())
|
||||
{
|
||||
final Iterator<L2ManufactureItem> it = _seller.getManufactureItems().values().iterator();
|
||||
L2ManufactureItem item;
|
||||
while (it.hasNext())
|
||||
_manufacture = new ArrayList<>();
|
||||
for (Entry<Integer, Long> item : _seller.getManufactureItems().entrySet())
|
||||
{
|
||||
item = it.next();
|
||||
if ((item.isDwarven() != _isDwarven) || !seller.hasRecipeList(item.getRecipeId()))
|
||||
final RecipeHolder recipe = RecipeData.getInstance().getRecipe(item.getKey());
|
||||
if (((recipe != null) && (recipe.isDwarvenRecipe() == _isDwarven)) && seller.hasRecipeList(recipe.getId()))
|
||||
{
|
||||
it.remove();
|
||||
_manufacture.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,34 +63,34 @@ public class RecipeShopManageList implements IClientOutgoingPacket
|
||||
packet.writeD((int) _seller.getAdena());
|
||||
packet.writeD(_isDwarven ? 0x00 : 0x01);
|
||||
|
||||
if (_recipes == null)
|
||||
if ((_recipes == null) || _recipes.isEmpty())
|
||||
{
|
||||
packet.writeD(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeD(_recipes.length); // number of items in recipe book
|
||||
packet.writeD(_recipes.size());// number of items in recipe book
|
||||
|
||||
for (int i = 0; i < _recipes.length; i++)
|
||||
int i = 1;
|
||||
for (RecipeHolder recipe : _recipes)
|
||||
{
|
||||
final L2RecipeList temp = _recipes[i];
|
||||
packet.writeD(temp.getId());
|
||||
packet.writeD(i + 1);
|
||||
packet.writeD(recipe.getId());
|
||||
packet.writeD(i++);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_seller.hasManufactureShop())
|
||||
if ((_manufacture == null) || _manufacture.isEmpty())
|
||||
{
|
||||
packet.writeD(0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeD(_seller.getManufactureItems().size());
|
||||
for (L2ManufactureItem item : _seller.getManufactureItems().values())
|
||||
packet.writeD(_manufacture.size());
|
||||
for (Entry<Integer, Long> item : _manufacture)
|
||||
{
|
||||
packet.writeD(item.getRecipeId());
|
||||
packet.writeD(0x00);
|
||||
packet.writeQ(item.getCost());
|
||||
packet.writeD(item.getKey());
|
||||
packet.writeD(0x00); // CanCraft?
|
||||
packet.writeQ(item.getValue());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -16,8 +16,9 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.model.L2ManufactureItem;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
@ -47,11 +48,11 @@ public class RecipeShopSellList implements IClientOutgoingPacket
|
||||
else
|
||||
{
|
||||
packet.writeD(_manufacturer.getManufactureItems().size());
|
||||
for (L2ManufactureItem temp : _manufacturer.getManufactureItems().values())
|
||||
for (Entry<Integer, Long> item : _manufacturer.getManufactureItems().entrySet())
|
||||
{
|
||||
packet.writeD(temp.getRecipeId());
|
||||
packet.writeD(0x00); // unknown
|
||||
packet.writeQ(temp.getCost());
|
||||
packet.writeD(item.getKey());
|
||||
packet.writeD(0x00); // CanCreate?
|
||||
packet.writeQ(item.getValue());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -76,7 +76,7 @@ public class SellList implements IClientOutgoingPacket
|
||||
|
||||
for (L2ItemInstance item : _sellList)
|
||||
{
|
||||
int price = item.getItem().getReferencePrice() / 2;
|
||||
long price = item.getItem().getReferencePrice() / 2;
|
||||
if (_merchant != null)
|
||||
{
|
||||
price -= (price * _merchant.getTotalTaxRate(TaxType.SELL));
|
||||
|
@ -23,6 +23,7 @@ import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.Product;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.items.type.CrystalType;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
public class ShopPreviewList implements IClientOutgoingPacket
|
||||
@ -30,14 +31,14 @@ public class ShopPreviewList implements IClientOutgoingPacket
|
||||
private final int _listId;
|
||||
private final Collection<Product> _list;
|
||||
private final long _money;
|
||||
private int _expertise;
|
||||
private CrystalType _expertise;
|
||||
|
||||
public ShopPreviewList(L2BuyList list, long currentMoney, int expertiseIndex)
|
||||
public ShopPreviewList(L2BuyList list, long currentMoney, CrystalType expertise)
|
||||
{
|
||||
_listId = list.getListId();
|
||||
_list = list.getProducts();
|
||||
_money = currentMoney;
|
||||
_expertise = expertiseIndex;
|
||||
_expertise = expertise;
|
||||
}
|
||||
|
||||
public ShopPreviewList(Collection<Product> lst, int listId, long currentMoney)
|
||||
@ -59,7 +60,7 @@ public class ShopPreviewList implements IClientOutgoingPacket
|
||||
int newlength = 0;
|
||||
for (Product product : _list)
|
||||
{
|
||||
if ((product.getItem().getCrystalType().getId() <= _expertise) && product.getItem().isEquipable())
|
||||
if (!product.getItem().getCrystalType().isGreater(_expertise) && product.getItem().isEquipable())
|
||||
{
|
||||
newlength++;
|
||||
}
|
||||
@ -68,7 +69,7 @@ public class ShopPreviewList implements IClientOutgoingPacket
|
||||
|
||||
for (Product product : _list)
|
||||
{
|
||||
if ((product.getItem().getCrystalType().getId() <= _expertise) && product.getItem().isEquipable())
|
||||
if (!product.getItem().getCrystalType().isGreater(_expertise) && product.getItem().isEquipable())
|
||||
{
|
||||
packet.writeD(product.getItemId());
|
||||
packet.writeH(product.getItem().getType2()); // item type2
|
||||
|
@ -20,6 +20,7 @@ import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
|
||||
import com.l2jmobius.gameserver.enums.AttributeType;
|
||||
import com.l2jmobius.gameserver.enums.ItemGrade;
|
||||
import com.l2jmobius.gameserver.enums.UserInfoType;
|
||||
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
@ -205,7 +206,7 @@ public class UserInfo extends AbstractMaskPacket<UserInfoType>
|
||||
packet.writeH(6);
|
||||
packet.writeC(_activeChar.getMountType().ordinal());
|
||||
packet.writeC(_activeChar.getPrivateStoreType().getId());
|
||||
packet.writeC(_activeChar.hasDwarvenCraft() || (_activeChar.getSkillLevel(248) > 0) ? 1 : 0);
|
||||
packet.writeC(_activeChar.getCrystallizeGrade() != ItemGrade.NONE ? 1 : 0);
|
||||
packet.writeC(_activeChar.getAbilityPoints() - _activeChar.getAbilityPointsUsed());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user