Support for henna duration and skills.
This commit is contained in:
parent
c777a4609a
commit
9894a46ce7
@ -26,20 +26,19 @@
|
||||
</xs:element>
|
||||
<xs:element name="cancel" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="count" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="count" type="xs:integer" use="required" />
|
||||
<xs:attribute name="fee" type="xs:integer" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skills" minOccurs="0">
|
||||
<xs:element name="duration" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="skill">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:positiveInteger" name="id" use="required"/>
|
||||
<xs:attribute type="xs:positiveInteger" name="level" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="time" type="xs:positiveInteger" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skill" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:positiveInteger" name="id" use="required"/>
|
||||
<xs:attribute type="xs:positiveInteger" name="level" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="classId" minOccurs="0" maxOccurs="unbounded">
|
||||
|
@ -31,13 +31,14 @@ import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.items.L2Henna;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* This class holds the henna related information.<br>
|
||||
* Cost and required amount to add the henna to the player.<br>
|
||||
* Cost and retrieved amount for removing the henna from the player.<br>
|
||||
* Allowed classes to wear each henna.
|
||||
* @author Zoey76
|
||||
* @author Zoey76, Mobius
|
||||
*/
|
||||
public final class HennaData implements IGameXmlReader
|
||||
{
|
||||
@ -87,6 +88,7 @@ public final class HennaData implements IGameXmlReader
|
||||
{
|
||||
final StatsSet set = new StatsSet();
|
||||
final List<ClassId> wearClassIds = new ArrayList<>();
|
||||
final List<Skill> skills = new ArrayList<>();
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
Node attr;
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
@ -126,6 +128,17 @@ public final class HennaData implements IGameXmlReader
|
||||
set.set("cancel_fee", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "duration":
|
||||
{
|
||||
attr = attrs.getNamedItem("time"); // in minutes
|
||||
set.set("duration", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "skill":
|
||||
{
|
||||
skills.add(SkillData.getInstance().getSkill(parseInteger(attrs, "id"), parseInteger(attrs, "level")));
|
||||
break;
|
||||
}
|
||||
case "classId":
|
||||
{
|
||||
wearClassIds.add(ClassId.getClassId(Integer.parseInt(c.getTextContent())));
|
||||
@ -134,6 +147,7 @@ public final class HennaData implements IGameXmlReader
|
||||
}
|
||||
}
|
||||
final L2Henna henna = new L2Henna(set);
|
||||
henna.setSkills(skills);
|
||||
henna.setWearClassIds(wearClassIds);
|
||||
_hennaList.put(henna.getDyeId(), henna);
|
||||
}
|
||||
|
@ -164,6 +164,7 @@ 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;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.PvPFlagTask;
|
||||
@ -595,9 +596,10 @@ public final class L2PcInstance extends L2Playable
|
||||
private final Set<L2PcInstance> _snoopListener = ConcurrentHashMap.newKeySet();
|
||||
private final Set<L2PcInstance> _snoopedPlayer = ConcurrentHashMap.newKeySet();
|
||||
|
||||
// hennas
|
||||
/** Hennas */
|
||||
private final L2Henna[] _henna = new L2Henna[3];
|
||||
private final Map<BaseStats, Integer> _hennaBaseStats = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(3);
|
||||
|
||||
/** The Pet of the L2PcInstance */
|
||||
private L2PetInstance _pet = null;
|
||||
@ -7752,9 +7754,9 @@ public final class L2PcInstance extends L2Playable
|
||||
*/
|
||||
private void restoreHenna()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
_henna[i] = null;
|
||||
_henna[i - 1] = null;
|
||||
}
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
@ -7779,7 +7781,28 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
continue;
|
||||
}
|
||||
_henna[slot - 1] = HennaData.getInstance().getHenna(symbolId);
|
||||
|
||||
final L2Henna henna = HennaData.getInstance().getHenna(symbolId);
|
||||
|
||||
// Task for henna duration
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
final long remainingTime = getVariables().getLong("HennaDuration" + slot, 0) - System.currentTimeMillis();
|
||||
if (remainingTime < 0)
|
||||
{
|
||||
removeHenna(slot);
|
||||
continue;
|
||||
}
|
||||
_hennaRemoveSchedules.put(slot, ThreadPoolManager.schedule(new HennaDurationTask(this, slot), System.currentTimeMillis() + remainingTime));
|
||||
}
|
||||
|
||||
_henna[slot - 1] = henna;
|
||||
|
||||
// Reward henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
addSkill(skill, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7835,27 +7858,25 @@ public final class L2PcInstance extends L2Playable
|
||||
return false;
|
||||
}
|
||||
|
||||
slot--;
|
||||
|
||||
final L2Henna henna = _henna[slot];
|
||||
final L2Henna henna = _henna[slot - 1];
|
||||
if (henna == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_henna[slot] = null;
|
||||
_henna[slot - 1] = null;
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(DELETE_CHAR_HENNA))
|
||||
{
|
||||
statement.setInt(1, getObjectId());
|
||||
statement.setInt(2, slot + 1);
|
||||
statement.setInt(2, slot);
|
||||
statement.setInt(3, getClassIndex());
|
||||
statement.execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed remocing character henna.", e);
|
||||
_log.log(Level.SEVERE, "Failed removing character henna.", e);
|
||||
}
|
||||
|
||||
// Calculate Henna modifiers of this L2PcInstance
|
||||
@ -7868,16 +7889,43 @@ public final class L2PcInstance extends L2Playable
|
||||
final UserInfo ui = new UserInfo(this, false);
|
||||
ui.addComponentType(UserInfoType.BASE_STATS, UserInfoType.MAX_HPCPMP, UserInfoType.STATS, UserInfoType.SPEED);
|
||||
sendPacket(ui);
|
||||
// Add the recovered dyes to the player's inventory and notify them.
|
||||
getInventory().addItem("Henna", henna.getDyeItemId(), henna.getCancelCount(), this, null);
|
||||
reduceAdena("Henna", henna.getCancelFee(), this, false);
|
||||
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(henna.getDyeItemId());
|
||||
sm.addLong(henna.getCancelCount());
|
||||
sendPacket(sm);
|
||||
final long remainingTime = getVariables().getLong("HennaDuration" + slot, 0) - System.currentTimeMillis();
|
||||
if ((henna.getDuration() < 0) || (remainingTime > 0))
|
||||
{
|
||||
// Add the recovered dyes to the player's inventory and notify them.
|
||||
if (henna.getCancelFee() > 0)
|
||||
{
|
||||
reduceAdena("Henna", henna.getCancelFee(), this, false);
|
||||
}
|
||||
if (henna.getCancelCount() > 0)
|
||||
{
|
||||
getInventory().addItem("Henna", henna.getDyeItemId(), henna.getCancelCount(), this, null);
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(henna.getDyeItemId());
|
||||
sm.addLong(henna.getCancelCount());
|
||||
sendPacket(sm);
|
||||
}
|
||||
}
|
||||
sendPacket(SystemMessageId.THE_SYMBOL_HAS_BEEN_DELETED);
|
||||
|
||||
// Remove henna duration task
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
getVariables().remove("HennaDuration" + slot);
|
||||
if (_hennaRemoveSchedules.get(slot) != null)
|
||||
{
|
||||
_hennaRemoveSchedules.get(slot).cancel(false);
|
||||
_hennaRemoveSchedules.remove(slot);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
removeSkill(skill, false);
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerHennaRemove(this, henna), this);
|
||||
return true;
|
||||
@ -7890,11 +7938,11 @@ public final class L2PcInstance extends L2Playable
|
||||
*/
|
||||
public boolean addHenna(L2Henna henna)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
if (_henna[i] == null)
|
||||
if (_henna[i - 1] == null)
|
||||
{
|
||||
_henna[i] = henna;
|
||||
_henna[i - 1] = henna;
|
||||
|
||||
// Calculate Henna modifiers of this L2PcInstance
|
||||
recalcHennaStats();
|
||||
@ -7904,7 +7952,7 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
statement.setInt(1, getObjectId());
|
||||
statement.setInt(2, henna.getDyeId());
|
||||
statement.setInt(3, i + 1);
|
||||
statement.setInt(3, i);
|
||||
statement.setInt(4, getClassIndex());
|
||||
statement.execute();
|
||||
}
|
||||
@ -7913,6 +7961,19 @@ public final class L2PcInstance extends L2Playable
|
||||
_log.log(Level.SEVERE, "Failed saving character henna.", e);
|
||||
}
|
||||
|
||||
// Task for henna duration
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
getVariables().set("HennaDuration" + i, System.currentTimeMillis() + (henna.getDuration() * 60000));
|
||||
_hennaRemoveSchedules.put(i, ThreadPoolManager.schedule(new HennaDurationTask(this, i), System.currentTimeMillis() + (henna.getDuration() * 60000)));
|
||||
}
|
||||
|
||||
// Reward henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
addSkill(skill, false);
|
||||
}
|
||||
|
||||
// Send Server->Client HennaInfo packet to this L2PcInstance
|
||||
sendPacket(new HennaInfo(this));
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.actor.tasks.player;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class HennaDurationTask implements Runnable
|
||||
{
|
||||
private final L2PcInstance _player;
|
||||
private final int _slot;
|
||||
|
||||
public HennaDurationTask(L2PcInstance player, int slot)
|
||||
{
|
||||
_player = player;
|
||||
_slot = slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (_player != null)
|
||||
{
|
||||
_player.removeHenna(_slot);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ import java.util.Map;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.stats.BaseStats;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
|
||||
@ -40,6 +41,8 @@ public class L2Henna
|
||||
private final int _wear_count;
|
||||
private final int _cancel_fee;
|
||||
private final int _cancel_count;
|
||||
private final int _duration;
|
||||
private final List<Skill> _skills;
|
||||
private final List<ClassId> _wear_class;
|
||||
|
||||
public L2Henna(StatsSet set)
|
||||
@ -59,6 +62,8 @@ public class L2Henna
|
||||
_wear_count = set.getInt("wear_count");
|
||||
_cancel_fee = set.getInt("cancel_fee");
|
||||
_cancel_count = set.getInt("cancel_count");
|
||||
_duration = set.getInt("duration", -1);
|
||||
_skills = new ArrayList<>();
|
||||
_wear_class = new ArrayList<>();
|
||||
}
|
||||
|
||||
@ -128,6 +133,30 @@ public class L2Henna
|
||||
return _cancel_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the duration of this dye.
|
||||
*/
|
||||
public int getDuration()
|
||||
{
|
||||
return _duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skillList the list of skills related to this dye.
|
||||
*/
|
||||
public void setSkills(List<Skill> skillList)
|
||||
{
|
||||
_skills.addAll(skillList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the skills related to this dye.
|
||||
*/
|
||||
public List<Skill> getSkills()
|
||||
{
|
||||
return _skills;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list with the allowed classes to wear this dye.
|
||||
*/
|
||||
|
@ -26,20 +26,19 @@
|
||||
</xs:element>
|
||||
<xs:element name="cancel" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="count" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="count" type="xs:integer" use="required" />
|
||||
<xs:attribute name="fee" type="xs:integer" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skills" minOccurs="0">
|
||||
<xs:element name="duration" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="skill">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:positiveInteger" name="id" use="required"/>
|
||||
<xs:attribute type="xs:positiveInteger" name="level" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="time" type="xs:positiveInteger" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skill" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:positiveInteger" name="id" use="required"/>
|
||||
<xs:attribute type="xs:positiveInteger" name="level" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="classId" minOccurs="0" maxOccurs="unbounded">
|
||||
|
@ -31,13 +31,14 @@ import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.items.L2Henna;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* This class holds the henna related information.<br>
|
||||
* Cost and required amount to add the henna to the player.<br>
|
||||
* Cost and retrieved amount for removing the henna from the player.<br>
|
||||
* Allowed classes to wear each henna.
|
||||
* @author Zoey76
|
||||
* @author Zoey76, Mobius
|
||||
*/
|
||||
public final class HennaData implements IGameXmlReader
|
||||
{
|
||||
@ -87,6 +88,7 @@ public final class HennaData implements IGameXmlReader
|
||||
{
|
||||
final StatsSet set = new StatsSet();
|
||||
final List<ClassId> wearClassIds = new ArrayList<>();
|
||||
final List<Skill> skills = new ArrayList<>();
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
Node attr;
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
@ -126,6 +128,17 @@ public final class HennaData implements IGameXmlReader
|
||||
set.set("cancel_fee", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "duration":
|
||||
{
|
||||
attr = attrs.getNamedItem("time"); // in minutes
|
||||
set.set("duration", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "skill":
|
||||
{
|
||||
skills.add(SkillData.getInstance().getSkill(parseInteger(attrs, "id"), parseInteger(attrs, "level")));
|
||||
break;
|
||||
}
|
||||
case "classId":
|
||||
{
|
||||
wearClassIds.add(ClassId.getClassId(Integer.parseInt(c.getTextContent())));
|
||||
@ -134,6 +147,7 @@ public final class HennaData implements IGameXmlReader
|
||||
}
|
||||
}
|
||||
final L2Henna henna = new L2Henna(set);
|
||||
henna.setSkills(skills);
|
||||
henna.setWearClassIds(wearClassIds);
|
||||
_hennaList.put(henna.getDyeId(), henna);
|
||||
}
|
||||
|
@ -163,6 +163,7 @@ 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;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.PvPFlagTask;
|
||||
@ -594,9 +595,10 @@ public final class L2PcInstance extends L2Playable
|
||||
private final Set<L2PcInstance> _snoopListener = ConcurrentHashMap.newKeySet();
|
||||
private final Set<L2PcInstance> _snoopedPlayer = ConcurrentHashMap.newKeySet();
|
||||
|
||||
// hennas
|
||||
/** Hennas */
|
||||
private final L2Henna[] _henna = new L2Henna[3];
|
||||
private final Map<BaseStats, Integer> _hennaBaseStats = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(3);
|
||||
|
||||
/** The Pet of the L2PcInstance */
|
||||
private L2PetInstance _pet = null;
|
||||
@ -7752,9 +7754,9 @@ public final class L2PcInstance extends L2Playable
|
||||
*/
|
||||
private void restoreHenna()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
_henna[i] = null;
|
||||
_henna[i - 1] = null;
|
||||
}
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
@ -7779,7 +7781,28 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
continue;
|
||||
}
|
||||
_henna[slot - 1] = HennaData.getInstance().getHenna(symbolId);
|
||||
|
||||
final L2Henna henna = HennaData.getInstance().getHenna(symbolId);
|
||||
|
||||
// Task for henna duration
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
final long remainingTime = getVariables().getLong("HennaDuration" + slot, 0) - System.currentTimeMillis();
|
||||
if (remainingTime < 0)
|
||||
{
|
||||
removeHenna(slot);
|
||||
continue;
|
||||
}
|
||||
_hennaRemoveSchedules.put(slot, ThreadPoolManager.schedule(new HennaDurationTask(this, slot), System.currentTimeMillis() + remainingTime));
|
||||
}
|
||||
|
||||
_henna[slot - 1] = henna;
|
||||
|
||||
// Reward henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
addSkill(skill, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7835,27 +7858,25 @@ public final class L2PcInstance extends L2Playable
|
||||
return false;
|
||||
}
|
||||
|
||||
slot--;
|
||||
|
||||
final L2Henna henna = _henna[slot];
|
||||
final L2Henna henna = _henna[slot - 1];
|
||||
if (henna == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_henna[slot] = null;
|
||||
_henna[slot - 1] = null;
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(DELETE_CHAR_HENNA))
|
||||
{
|
||||
statement.setInt(1, getObjectId());
|
||||
statement.setInt(2, slot + 1);
|
||||
statement.setInt(2, slot);
|
||||
statement.setInt(3, getClassIndex());
|
||||
statement.execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed remocing character henna.", e);
|
||||
_log.log(Level.SEVERE, "Failed removing character henna.", e);
|
||||
}
|
||||
|
||||
// Calculate Henna modifiers of this L2PcInstance
|
||||
@ -7868,16 +7889,43 @@ public final class L2PcInstance extends L2Playable
|
||||
final UserInfo ui = new UserInfo(this, false);
|
||||
ui.addComponentType(UserInfoType.BASE_STATS, UserInfoType.MAX_HPCPMP, UserInfoType.STATS, UserInfoType.SPEED);
|
||||
sendPacket(ui);
|
||||
// Add the recovered dyes to the player's inventory and notify them.
|
||||
getInventory().addItem("Henna", henna.getDyeItemId(), henna.getCancelCount(), this, null);
|
||||
reduceAdena("Henna", henna.getCancelFee(), this, false);
|
||||
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(henna.getDyeItemId());
|
||||
sm.addLong(henna.getCancelCount());
|
||||
sendPacket(sm);
|
||||
final long remainingTime = getVariables().getLong("HennaDuration" + slot, 0) - System.currentTimeMillis();
|
||||
if ((henna.getDuration() < 0) || (remainingTime > 0))
|
||||
{
|
||||
// Add the recovered dyes to the player's inventory and notify them.
|
||||
if (henna.getCancelFee() > 0)
|
||||
{
|
||||
reduceAdena("Henna", henna.getCancelFee(), this, false);
|
||||
}
|
||||
if (henna.getCancelCount() > 0)
|
||||
{
|
||||
getInventory().addItem("Henna", henna.getDyeItemId(), henna.getCancelCount(), this, null);
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(henna.getDyeItemId());
|
||||
sm.addLong(henna.getCancelCount());
|
||||
sendPacket(sm);
|
||||
}
|
||||
}
|
||||
sendPacket(SystemMessageId.THE_SYMBOL_HAS_BEEN_DELETED);
|
||||
|
||||
// Remove henna duration task
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
getVariables().remove("HennaDuration" + slot);
|
||||
if (_hennaRemoveSchedules.get(slot) != null)
|
||||
{
|
||||
_hennaRemoveSchedules.get(slot).cancel(false);
|
||||
_hennaRemoveSchedules.remove(slot);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
removeSkill(skill, false);
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerHennaRemove(this, henna), this);
|
||||
return true;
|
||||
@ -7890,11 +7938,11 @@ public final class L2PcInstance extends L2Playable
|
||||
*/
|
||||
public boolean addHenna(L2Henna henna)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
if (_henna[i] == null)
|
||||
if (_henna[i - 1] == null)
|
||||
{
|
||||
_henna[i] = henna;
|
||||
_henna[i - 1] = henna;
|
||||
|
||||
// Calculate Henna modifiers of this L2PcInstance
|
||||
recalcHennaStats();
|
||||
@ -7904,7 +7952,7 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
statement.setInt(1, getObjectId());
|
||||
statement.setInt(2, henna.getDyeId());
|
||||
statement.setInt(3, i + 1);
|
||||
statement.setInt(3, i);
|
||||
statement.setInt(4, getClassIndex());
|
||||
statement.execute();
|
||||
}
|
||||
@ -7913,6 +7961,19 @@ public final class L2PcInstance extends L2Playable
|
||||
_log.log(Level.SEVERE, "Failed saving character henna.", e);
|
||||
}
|
||||
|
||||
// Task for henna duration
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
getVariables().set("HennaDuration" + i, System.currentTimeMillis() + (henna.getDuration() * 60000));
|
||||
_hennaRemoveSchedules.put(i, ThreadPoolManager.schedule(new HennaDurationTask(this, i), System.currentTimeMillis() + (henna.getDuration() * 60000)));
|
||||
}
|
||||
|
||||
// Reward henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
addSkill(skill, false);
|
||||
}
|
||||
|
||||
// Send Server->Client HennaInfo packet to this L2PcInstance
|
||||
sendPacket(new HennaInfo(this));
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.actor.tasks.player;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class HennaDurationTask implements Runnable
|
||||
{
|
||||
private final L2PcInstance _player;
|
||||
private final int _slot;
|
||||
|
||||
public HennaDurationTask(L2PcInstance player, int slot)
|
||||
{
|
||||
_player = player;
|
||||
_slot = slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (_player != null)
|
||||
{
|
||||
_player.removeHenna(_slot);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ import java.util.Map;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.stats.BaseStats;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
|
||||
@ -40,6 +41,8 @@ public class L2Henna
|
||||
private final int _wear_count;
|
||||
private final int _cancel_fee;
|
||||
private final int _cancel_count;
|
||||
private final int _duration;
|
||||
private final List<Skill> _skills;
|
||||
private final List<ClassId> _wear_class;
|
||||
|
||||
public L2Henna(StatsSet set)
|
||||
@ -59,6 +62,8 @@ public class L2Henna
|
||||
_wear_count = set.getInt("wear_count");
|
||||
_cancel_fee = set.getInt("cancel_fee");
|
||||
_cancel_count = set.getInt("cancel_count");
|
||||
_duration = set.getInt("duration", -1);
|
||||
_skills = new ArrayList<>();
|
||||
_wear_class = new ArrayList<>();
|
||||
}
|
||||
|
||||
@ -128,6 +133,30 @@ public class L2Henna
|
||||
return _cancel_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the duration of this dye.
|
||||
*/
|
||||
public int getDuration()
|
||||
{
|
||||
return _duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skillList the list of skills related to this dye.
|
||||
*/
|
||||
public void setSkills(List<Skill> skillList)
|
||||
{
|
||||
_skills.addAll(skillList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the skills related to this dye.
|
||||
*/
|
||||
public List<Skill> getSkills()
|
||||
{
|
||||
return _skills;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list with the allowed classes to wear this dye.
|
||||
*/
|
||||
|
@ -26,20 +26,19 @@
|
||||
</xs:element>
|
||||
<xs:element name="cancel" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="count" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="count" type="xs:integer" use="required" />
|
||||
<xs:attribute name="fee" type="xs:integer" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skills" minOccurs="0">
|
||||
<xs:element name="duration" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="skill">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:positiveInteger" name="id" use="required"/>
|
||||
<xs:attribute type="xs:positiveInteger" name="level" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="time" type="xs:positiveInteger" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skill" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:positiveInteger" name="id" use="required"/>
|
||||
<xs:attribute type="xs:positiveInteger" name="level" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="classId" minOccurs="0" maxOccurs="unbounded">
|
||||
|
@ -31,13 +31,14 @@ import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.items.L2Henna;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* This class holds the henna related information.<br>
|
||||
* Cost and required amount to add the henna to the player.<br>
|
||||
* Cost and retrieved amount for removing the henna from the player.<br>
|
||||
* Allowed classes to wear each henna.
|
||||
* @author Zoey76
|
||||
* @author Zoey76, Mobius
|
||||
*/
|
||||
public final class HennaData implements IGameXmlReader
|
||||
{
|
||||
@ -87,6 +88,7 @@ public final class HennaData implements IGameXmlReader
|
||||
{
|
||||
final StatsSet set = new StatsSet();
|
||||
final List<ClassId> wearClassIds = new ArrayList<>();
|
||||
final List<Skill> skills = new ArrayList<>();
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
Node attr;
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
@ -126,6 +128,17 @@ public final class HennaData implements IGameXmlReader
|
||||
set.set("cancel_fee", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "duration":
|
||||
{
|
||||
attr = attrs.getNamedItem("time"); // in minutes
|
||||
set.set("duration", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "skill":
|
||||
{
|
||||
skills.add(SkillData.getInstance().getSkill(parseInteger(attrs, "id"), parseInteger(attrs, "level")));
|
||||
break;
|
||||
}
|
||||
case "classId":
|
||||
{
|
||||
wearClassIds.add(ClassId.getClassId(Integer.parseInt(c.getTextContent())));
|
||||
@ -134,6 +147,7 @@ public final class HennaData implements IGameXmlReader
|
||||
}
|
||||
}
|
||||
final L2Henna henna = new L2Henna(set);
|
||||
henna.setSkills(skills);
|
||||
henna.setWearClassIds(wearClassIds);
|
||||
_hennaList.put(henna.getDyeId(), henna);
|
||||
}
|
||||
|
@ -164,6 +164,7 @@ 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;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.PvPFlagTask;
|
||||
@ -596,9 +597,10 @@ public final class L2PcInstance extends L2Playable
|
||||
private final Set<L2PcInstance> _snoopListener = ConcurrentHashMap.newKeySet();
|
||||
private final Set<L2PcInstance> _snoopedPlayer = ConcurrentHashMap.newKeySet();
|
||||
|
||||
// hennas
|
||||
/** Hennas */
|
||||
private final L2Henna[] _henna = new L2Henna[3];
|
||||
private final Map<BaseStats, Integer> _hennaBaseStats = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(3);
|
||||
|
||||
/** The Pet of the L2PcInstance */
|
||||
private L2PetInstance _pet = null;
|
||||
@ -7754,9 +7756,9 @@ public final class L2PcInstance extends L2Playable
|
||||
*/
|
||||
private void restoreHenna()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
_henna[i] = null;
|
||||
_henna[i - 1] = null;
|
||||
}
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
@ -7781,7 +7783,28 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
continue;
|
||||
}
|
||||
_henna[slot - 1] = HennaData.getInstance().getHenna(symbolId);
|
||||
|
||||
final L2Henna henna = HennaData.getInstance().getHenna(symbolId);
|
||||
|
||||
// Task for henna duration
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
final long remainingTime = getVariables().getLong("HennaDuration" + slot, 0) - System.currentTimeMillis();
|
||||
if (remainingTime < 0)
|
||||
{
|
||||
removeHenna(slot);
|
||||
continue;
|
||||
}
|
||||
_hennaRemoveSchedules.put(slot, ThreadPoolManager.schedule(new HennaDurationTask(this, slot), System.currentTimeMillis() + remainingTime));
|
||||
}
|
||||
|
||||
_henna[slot - 1] = henna;
|
||||
|
||||
// Reward henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
addSkill(skill, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7837,27 +7860,25 @@ public final class L2PcInstance extends L2Playable
|
||||
return false;
|
||||
}
|
||||
|
||||
slot--;
|
||||
|
||||
final L2Henna henna = _henna[slot];
|
||||
final L2Henna henna = _henna[slot - 1];
|
||||
if (henna == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_henna[slot] = null;
|
||||
_henna[slot - 1] = null;
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(DELETE_CHAR_HENNA))
|
||||
{
|
||||
statement.setInt(1, getObjectId());
|
||||
statement.setInt(2, slot + 1);
|
||||
statement.setInt(2, slot);
|
||||
statement.setInt(3, getClassIndex());
|
||||
statement.execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed remocing character henna.", e);
|
||||
_log.log(Level.SEVERE, "Failed removing character henna.", e);
|
||||
}
|
||||
|
||||
// Calculate Henna modifiers of this L2PcInstance
|
||||
@ -7870,16 +7891,43 @@ public final class L2PcInstance extends L2Playable
|
||||
final UserInfo ui = new UserInfo(this, false);
|
||||
ui.addComponentType(UserInfoType.BASE_STATS, UserInfoType.MAX_HPCPMP, UserInfoType.STATS, UserInfoType.SPEED);
|
||||
sendPacket(ui);
|
||||
// Add the recovered dyes to the player's inventory and notify them.
|
||||
getInventory().addItem("Henna", henna.getDyeItemId(), henna.getCancelCount(), this, null);
|
||||
reduceAdena("Henna", henna.getCancelFee(), this, false);
|
||||
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(henna.getDyeItemId());
|
||||
sm.addLong(henna.getCancelCount());
|
||||
sendPacket(sm);
|
||||
final long remainingTime = getVariables().getLong("HennaDuration" + slot, 0) - System.currentTimeMillis();
|
||||
if ((henna.getDuration() < 0) || (remainingTime > 0))
|
||||
{
|
||||
// Add the recovered dyes to the player's inventory and notify them.
|
||||
if (henna.getCancelFee() > 0)
|
||||
{
|
||||
reduceAdena("Henna", henna.getCancelFee(), this, false);
|
||||
}
|
||||
if (henna.getCancelCount() > 0)
|
||||
{
|
||||
getInventory().addItem("Henna", henna.getDyeItemId(), henna.getCancelCount(), this, null);
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(henna.getDyeItemId());
|
||||
sm.addLong(henna.getCancelCount());
|
||||
sendPacket(sm);
|
||||
}
|
||||
}
|
||||
sendPacket(SystemMessageId.THE_SYMBOL_HAS_BEEN_DELETED);
|
||||
|
||||
// Remove henna duration task
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
getVariables().remove("HennaDuration" + slot);
|
||||
if (_hennaRemoveSchedules.get(slot) != null)
|
||||
{
|
||||
_hennaRemoveSchedules.get(slot).cancel(false);
|
||||
_hennaRemoveSchedules.remove(slot);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
removeSkill(skill, false);
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerHennaRemove(this, henna), this);
|
||||
return true;
|
||||
@ -7892,11 +7940,11 @@ public final class L2PcInstance extends L2Playable
|
||||
*/
|
||||
public boolean addHenna(L2Henna henna)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
if (_henna[i] == null)
|
||||
if (_henna[i - 1] == null)
|
||||
{
|
||||
_henna[i] = henna;
|
||||
_henna[i - 1] = henna;
|
||||
|
||||
// Calculate Henna modifiers of this L2PcInstance
|
||||
recalcHennaStats();
|
||||
@ -7906,7 +7954,7 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
statement.setInt(1, getObjectId());
|
||||
statement.setInt(2, henna.getDyeId());
|
||||
statement.setInt(3, i + 1);
|
||||
statement.setInt(3, i);
|
||||
statement.setInt(4, getClassIndex());
|
||||
statement.execute();
|
||||
}
|
||||
@ -7915,6 +7963,19 @@ public final class L2PcInstance extends L2Playable
|
||||
_log.log(Level.SEVERE, "Failed saving character henna.", e);
|
||||
}
|
||||
|
||||
// Task for henna duration
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
getVariables().set("HennaDuration" + i, System.currentTimeMillis() + (henna.getDuration() * 60000));
|
||||
_hennaRemoveSchedules.put(i, ThreadPoolManager.schedule(new HennaDurationTask(this, i), System.currentTimeMillis() + (henna.getDuration() * 60000)));
|
||||
}
|
||||
|
||||
// Reward henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
addSkill(skill, false);
|
||||
}
|
||||
|
||||
// Send Server->Client HennaInfo packet to this L2PcInstance
|
||||
sendPacket(new HennaInfo(this));
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.actor.tasks.player;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class HennaDurationTask implements Runnable
|
||||
{
|
||||
private final L2PcInstance _player;
|
||||
private final int _slot;
|
||||
|
||||
public HennaDurationTask(L2PcInstance player, int slot)
|
||||
{
|
||||
_player = player;
|
||||
_slot = slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (_player != null)
|
||||
{
|
||||
_player.removeHenna(_slot);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ import java.util.Map;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.stats.BaseStats;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
|
||||
@ -40,6 +41,8 @@ public class L2Henna
|
||||
private final int _wear_count;
|
||||
private final int _cancel_fee;
|
||||
private final int _cancel_count;
|
||||
private final int _duration;
|
||||
private final List<Skill> _skills;
|
||||
private final List<ClassId> _wear_class;
|
||||
|
||||
public L2Henna(StatsSet set)
|
||||
@ -59,6 +62,8 @@ public class L2Henna
|
||||
_wear_count = set.getInt("wear_count");
|
||||
_cancel_fee = set.getInt("cancel_fee");
|
||||
_cancel_count = set.getInt("cancel_count");
|
||||
_duration = set.getInt("duration", -1);
|
||||
_skills = new ArrayList<>();
|
||||
_wear_class = new ArrayList<>();
|
||||
}
|
||||
|
||||
@ -128,6 +133,30 @@ public class L2Henna
|
||||
return _cancel_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the duration of this dye.
|
||||
*/
|
||||
public int getDuration()
|
||||
{
|
||||
return _duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skillList the list of skills related to this dye.
|
||||
*/
|
||||
public void setSkills(List<Skill> skillList)
|
||||
{
|
||||
_skills.addAll(skillList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the skills related to this dye.
|
||||
*/
|
||||
public List<Skill> getSkills()
|
||||
{
|
||||
return _skills;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list with the allowed classes to wear this dye.
|
||||
*/
|
||||
|
@ -26,20 +26,19 @@
|
||||
</xs:element>
|
||||
<xs:element name="cancel" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="count" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="count" type="xs:integer" use="required" />
|
||||
<xs:attribute name="fee" type="xs:integer" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skills" minOccurs="0">
|
||||
<xs:element name="duration" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="skill">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:positiveInteger" name="id" use="required"/>
|
||||
<xs:attribute type="xs:positiveInteger" name="level" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="time" type="xs:positiveInteger" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skill" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:positiveInteger" name="id" use="required"/>
|
||||
<xs:attribute type="xs:positiveInteger" name="level" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="classId" minOccurs="0" maxOccurs="unbounded">
|
||||
|
@ -31,13 +31,14 @@ import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.items.L2Henna;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* This class holds the henna related information.<br>
|
||||
* Cost and required amount to add the henna to the player.<br>
|
||||
* Cost and retrieved amount for removing the henna from the player.<br>
|
||||
* Allowed classes to wear each henna.
|
||||
* @author Zoey76
|
||||
* @author Zoey76, Mobius
|
||||
*/
|
||||
public final class HennaData implements IGameXmlReader
|
||||
{
|
||||
@ -87,6 +88,7 @@ public final class HennaData implements IGameXmlReader
|
||||
{
|
||||
final StatsSet set = new StatsSet();
|
||||
final List<ClassId> wearClassIds = new ArrayList<>();
|
||||
final List<Skill> skills = new ArrayList<>();
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
Node attr;
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
@ -126,6 +128,17 @@ public final class HennaData implements IGameXmlReader
|
||||
set.set("cancel_fee", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "duration":
|
||||
{
|
||||
attr = attrs.getNamedItem("time"); // in minutes
|
||||
set.set("duration", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "skill":
|
||||
{
|
||||
skills.add(SkillData.getInstance().getSkill(parseInteger(attrs, "id"), parseInteger(attrs, "level")));
|
||||
break;
|
||||
}
|
||||
case "classId":
|
||||
{
|
||||
wearClassIds.add(ClassId.getClassId(Integer.parseInt(c.getTextContent())));
|
||||
@ -134,6 +147,7 @@ public final class HennaData implements IGameXmlReader
|
||||
}
|
||||
}
|
||||
final L2Henna henna = new L2Henna(set);
|
||||
henna.setSkills(skills);
|
||||
henna.setWearClassIds(wearClassIds);
|
||||
_hennaList.put(henna.getDyeId(), henna);
|
||||
}
|
||||
|
@ -163,6 +163,7 @@ 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;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.PvPFlagTask;
|
||||
@ -593,9 +594,10 @@ public final class L2PcInstance extends L2Playable
|
||||
private final Set<L2PcInstance> _snoopListener = ConcurrentHashMap.newKeySet();
|
||||
private final Set<L2PcInstance> _snoopedPlayer = ConcurrentHashMap.newKeySet();
|
||||
|
||||
// hennas
|
||||
/** Hennas */
|
||||
private final L2Henna[] _henna = new L2Henna[3];
|
||||
private final Map<BaseStats, Integer> _hennaBaseStats = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(3);
|
||||
|
||||
/** The Pet of the L2PcInstance */
|
||||
private L2PetInstance _pet = null;
|
||||
@ -7724,9 +7726,9 @@ public final class L2PcInstance extends L2Playable
|
||||
*/
|
||||
private void restoreHenna()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
_henna[i] = null;
|
||||
_henna[i - 1] = null;
|
||||
}
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
@ -7751,7 +7753,28 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
continue;
|
||||
}
|
||||
_henna[slot - 1] = HennaData.getInstance().getHenna(symbolId);
|
||||
|
||||
final L2Henna henna = HennaData.getInstance().getHenna(symbolId);
|
||||
|
||||
// Task for henna duration
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
final long remainingTime = getVariables().getLong("HennaDuration" + slot, 0) - System.currentTimeMillis();
|
||||
if (remainingTime < 0)
|
||||
{
|
||||
removeHenna(slot);
|
||||
continue;
|
||||
}
|
||||
_hennaRemoveSchedules.put(slot, ThreadPoolManager.schedule(new HennaDurationTask(this, slot), System.currentTimeMillis() + remainingTime));
|
||||
}
|
||||
|
||||
_henna[slot - 1] = henna;
|
||||
|
||||
// Reward henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
addSkill(skill, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7807,27 +7830,25 @@ public final class L2PcInstance extends L2Playable
|
||||
return false;
|
||||
}
|
||||
|
||||
slot--;
|
||||
|
||||
final L2Henna henna = _henna[slot];
|
||||
final L2Henna henna = _henna[slot - 1];
|
||||
if (henna == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_henna[slot] = null;
|
||||
_henna[slot - 1] = null;
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(DELETE_CHAR_HENNA))
|
||||
{
|
||||
statement.setInt(1, getObjectId());
|
||||
statement.setInt(2, slot + 1);
|
||||
statement.setInt(2, slot);
|
||||
statement.setInt(3, getClassIndex());
|
||||
statement.execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed remocing character henna.", e);
|
||||
_log.log(Level.SEVERE, "Failed removing character henna.", e);
|
||||
}
|
||||
|
||||
// Calculate Henna modifiers of this L2PcInstance
|
||||
@ -7840,16 +7861,43 @@ public final class L2PcInstance extends L2Playable
|
||||
final UserInfo ui = new UserInfo(this, false);
|
||||
ui.addComponentType(UserInfoType.BASE_STATS, UserInfoType.MAX_HPCPMP, UserInfoType.STATS, UserInfoType.SPEED);
|
||||
sendPacket(ui);
|
||||
// Add the recovered dyes to the player's inventory and notify them.
|
||||
getInventory().addItem("Henna", henna.getDyeItemId(), henna.getCancelCount(), this, null);
|
||||
reduceAdena("Henna", henna.getCancelFee(), this, false);
|
||||
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(henna.getDyeItemId());
|
||||
sm.addLong(henna.getCancelCount());
|
||||
sendPacket(sm);
|
||||
final long remainingTime = getVariables().getLong("HennaDuration" + slot, 0) - System.currentTimeMillis();
|
||||
if ((henna.getDuration() < 0) || (remainingTime > 0))
|
||||
{
|
||||
// Add the recovered dyes to the player's inventory and notify them.
|
||||
if (henna.getCancelFee() > 0)
|
||||
{
|
||||
reduceAdena("Henna", henna.getCancelFee(), this, false);
|
||||
}
|
||||
if (henna.getCancelCount() > 0)
|
||||
{
|
||||
getInventory().addItem("Henna", henna.getDyeItemId(), henna.getCancelCount(), this, null);
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(henna.getDyeItemId());
|
||||
sm.addLong(henna.getCancelCount());
|
||||
sendPacket(sm);
|
||||
}
|
||||
}
|
||||
sendPacket(SystemMessageId.THE_SYMBOL_HAS_BEEN_DELETED);
|
||||
|
||||
// Remove henna duration task
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
getVariables().remove("HennaDuration" + slot);
|
||||
if (_hennaRemoveSchedules.get(slot) != null)
|
||||
{
|
||||
_hennaRemoveSchedules.get(slot).cancel(false);
|
||||
_hennaRemoveSchedules.remove(slot);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
removeSkill(skill, false);
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerHennaRemove(this, henna), this);
|
||||
return true;
|
||||
@ -7862,11 +7910,11 @@ public final class L2PcInstance extends L2Playable
|
||||
*/
|
||||
public boolean addHenna(L2Henna henna)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
if (_henna[i] == null)
|
||||
if (_henna[i - 1] == null)
|
||||
{
|
||||
_henna[i] = henna;
|
||||
_henna[i - 1] = henna;
|
||||
|
||||
// Calculate Henna modifiers of this L2PcInstance
|
||||
recalcHennaStats();
|
||||
@ -7876,7 +7924,7 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
statement.setInt(1, getObjectId());
|
||||
statement.setInt(2, henna.getDyeId());
|
||||
statement.setInt(3, i + 1);
|
||||
statement.setInt(3, i);
|
||||
statement.setInt(4, getClassIndex());
|
||||
statement.execute();
|
||||
}
|
||||
@ -7885,6 +7933,19 @@ public final class L2PcInstance extends L2Playable
|
||||
_log.log(Level.SEVERE, "Failed saving character henna.", e);
|
||||
}
|
||||
|
||||
// Task for henna duration
|
||||
if (henna.getDuration() > 0)
|
||||
{
|
||||
getVariables().set("HennaDuration" + i, System.currentTimeMillis() + (henna.getDuration() * 60000));
|
||||
_hennaRemoveSchedules.put(i, ThreadPoolManager.schedule(new HennaDurationTask(this, i), System.currentTimeMillis() + (henna.getDuration() * 60000)));
|
||||
}
|
||||
|
||||
// Reward henna skills
|
||||
for (Skill skill : henna.getSkills())
|
||||
{
|
||||
addSkill(skill, false);
|
||||
}
|
||||
|
||||
// Send Server->Client HennaInfo packet to this L2PcInstance
|
||||
sendPacket(new HennaInfo(this));
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.actor.tasks.player;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class HennaDurationTask implements Runnable
|
||||
{
|
||||
private final L2PcInstance _player;
|
||||
private final int _slot;
|
||||
|
||||
public HennaDurationTask(L2PcInstance player, int slot)
|
||||
{
|
||||
_player = player;
|
||||
_slot = slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (_player != null)
|
||||
{
|
||||
_player.removeHenna(_slot);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ import java.util.Map;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.stats.BaseStats;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
|
||||
@ -40,6 +41,8 @@ public class L2Henna
|
||||
private final int _wear_count;
|
||||
private final int _cancel_fee;
|
||||
private final int _cancel_count;
|
||||
private final int _duration;
|
||||
private final List<Skill> _skills;
|
||||
private final List<ClassId> _wear_class;
|
||||
|
||||
public L2Henna(StatsSet set)
|
||||
@ -59,6 +62,8 @@ public class L2Henna
|
||||
_wear_count = set.getInt("wear_count");
|
||||
_cancel_fee = set.getInt("cancel_fee");
|
||||
_cancel_count = set.getInt("cancel_count");
|
||||
_duration = set.getInt("duration", -1);
|
||||
_skills = new ArrayList<>();
|
||||
_wear_class = new ArrayList<>();
|
||||
}
|
||||
|
||||
@ -128,6 +133,30 @@ public class L2Henna
|
||||
return _cancel_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the duration of this dye.
|
||||
*/
|
||||
public int getDuration()
|
||||
{
|
||||
return _duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skillList the list of skills related to this dye.
|
||||
*/
|
||||
public void setSkills(List<Skill> skillList)
|
||||
{
|
||||
_skills.addAll(skillList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the skills related to this dye.
|
||||
*/
|
||||
public List<Skill> getSkills()
|
||||
{
|
||||
return _skills;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list with the allowed classes to wear this dye.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user