diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/game/config/MagicLamp.ini b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/game/config/MagicLamp.ini
new file mode 100644
index 0000000000..44f690db22
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/game/config/MagicLamp.ini
@@ -0,0 +1,15 @@
+# ---------------------------------------------------------------------------
+# Magic Lamp Settings
+# ---------------------------------------------------------------------------
+
+MagicLampEnabled = False
+
+MagicLampMaxGames = 300
+
+MagicLampRewardCount = 1
+
+MagicLampGreaterRewardCount = 10
+
+MagicLampMaxLevelExp = 10000000
+
+MagicLampChargeRate = 0.1
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/game/data/MagicLampData.xml b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/game/data/MagicLampData.xml
new file mode 100644
index 0000000000..0cd284c5fb
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/game/data/MagicLampData.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/game/data/xsd/MagicLampData.xsd b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/game/data/xsd/MagicLampData.xsd
new file mode 100644
index 0000000000..ead1fca8b6
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/game/data/xsd/MagicLampData.xsd
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/Config.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/Config.java
index caf06b4e93..c679851f51 100644
--- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/Config.java
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/Config.java
@@ -106,6 +106,7 @@ public class Config
private static final String CHAT_FILTER_FILE = "./config/chatfilter.txt";
private static final String HEXID_FILE = "./config/hexid.txt";
private static final String IPCONFIG_FILE = "./config/ipconfig.xml";
+ private static final String MAGIC_LAMP_FILE = "./config/MagicLamp.ini";
// --------------------------------------------------
// Custom Config File Definitions
@@ -855,6 +856,14 @@ public class Config
public static boolean ENABLE_CMD_LINE_LOGIN;
public static boolean ONLY_CMD_LINE_LOGIN;
+ // Magic Lamp
+ public static boolean MAGIC_LAMP_ENABLE;
+ public static int MAGIC_LAMP_MAX_GAME_COUNT;
+ public static int MAGIC_LAMP_REWARD_COUNT;
+ public static int MAGIC_LAMP_GREATER_REWARD_COUNT;
+ public static int MAGIC_LAMP_MAX_LEVEL_EXP;
+ public static double MAGIC_LAMP_CHARGE_RATE;
+
// GrandBoss Settings
// Antharas
@@ -1875,6 +1884,15 @@ public class Config
TIME_LIMITED_ZONE_RESET_DELAY = timeLimitedZoneSettings.getLong("ResetDelay", 36000000);
TIME_LIMITED_ZONE_TELEPORT_FEE = timeLimitedZoneSettings.getLong("TeleportFee", 10000);
+ // Load Training Camp config file (if exists)
+ final PropertiesParser magicLampSettings = new PropertiesParser(MAGIC_LAMP_FILE);
+ MAGIC_LAMP_ENABLE = magicLampSettings.getBoolean("MagicLampEnabled", false);
+ MAGIC_LAMP_MAX_GAME_COUNT = magicLampSettings.getInt("MagicLampMaxGames", 300);
+ MAGIC_LAMP_REWARD_COUNT = magicLampSettings.getInt("MagicLampRewardCount", 1);
+ MAGIC_LAMP_GREATER_REWARD_COUNT = magicLampSettings.getInt("MagicLampGreaterRewardCount", 10);
+ MAGIC_LAMP_MAX_LEVEL_EXP = magicLampSettings.getInt("MagicLampMaxLevelExp", 10000000);
+ MAGIC_LAMP_CHARGE_RATE = magicLampSettings.getDouble("MagicLampChargeRate", 0.1);
+
// Load Training Camp config file (if exists)
final PropertiesParser trainingCampSettings = new PropertiesParser(TRAINING_CAMP_CONFIG_FILE);
TRAINING_CAMP_ENABLE = trainingCampSettings.getBoolean("TrainingCampEnable", false);
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/GameServer.java
index b63743b697..fca5561c97 100644
--- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/GameServer.java
@@ -81,6 +81,7 @@ import org.l2jmobius.gameserver.data.xml.ItemCrystallizationData;
import org.l2jmobius.gameserver.data.xml.KarmaData;
import org.l2jmobius.gameserver.data.xml.LCoinShopData;
import org.l2jmobius.gameserver.data.xml.LuckyGameData;
+import org.l2jmobius.gameserver.data.xml.MagicLampData;
import org.l2jmobius.gameserver.data.xml.MultisellData;
import org.l2jmobius.gameserver.data.xml.NpcData;
import org.l2jmobius.gameserver.data.xml.NpcNameLocalisationData;
@@ -283,6 +284,7 @@ public class GameServer
CommissionManager.getInstance();
LuckyGameData.getInstance();
AttendanceRewardData.getInstance();
+ MagicLampData.getInstance();
printSection("Characters");
ClassListData.getInstance();
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/xml/MagicLampData.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/xml/MagicLampData.java
new file mode 100644
index 0000000000..86db299d3f
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/data/xml/MagicLampData.java
@@ -0,0 +1,106 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.data.xml;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Document;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.IXmlReader;
+import org.l2jmobius.gameserver.model.StatSet;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.GreaterMagicLampHolder;
+import org.l2jmobius.gameserver.model.holders.MagicLampDataHolder;
+import org.l2jmobius.gameserver.network.serverpackets.magiclamp.ExMagicLampExpInfoUI;
+
+/**
+ * @author L2CCCP
+ */
+public class MagicLampData implements IXmlReader
+{
+ private static final List LAMPS = new ArrayList<>();
+ private static final List GREATER_LAMPS = new ArrayList<>();
+
+ protected MagicLampData()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ LAMPS.clear();
+ GREATER_LAMPS.clear();
+ parseDatapackFile("data/MagicLampData.xml");
+ LOGGER.info("MagicLampData: Loaded " + (LAMPS.size() + GREATER_LAMPS.size()) + " magic lamps.");
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ forEach(doc, "list", listNode -> forEach(listNode, node ->
+ {
+ if (node.getNodeName().equalsIgnoreCase("greater_lamp_mode"))
+ {
+ GREATER_LAMPS.add(new GreaterMagicLampHolder(new StatSet(parseAttributes(node))));
+ }
+ else if (node.getNodeName().equalsIgnoreCase("lamp"))
+ {
+ LAMPS.add(new MagicLampDataHolder(new StatSet(parseAttributes(node))));
+ }
+ }));
+ }
+
+ public void addLampExp(final PlayerInstance player, final double exp)
+ {
+ if (Config.MAGIC_LAMP_ENABLE)
+ {
+ final int lampExp = (int) (exp * Config.MAGIC_LAMP_CHARGE_RATE);
+ int calc = lampExp + player.getLampExp();
+ if (calc > Config.MAGIC_LAMP_MAX_LEVEL_EXP)
+ {
+ calc %= Config.MAGIC_LAMP_MAX_LEVEL_EXP;
+ player.setLampCount(player.getLampCount() + 1);
+ }
+ player.setLampExp(calc);
+ player.sendPacket(new ExMagicLampExpInfoUI(player));
+ }
+ }
+
+ public List getLamps()
+ {
+ return LAMPS;
+ }
+
+ public List getGreaterLamps()
+ {
+ return GREATER_LAMPS;
+ }
+
+ public static MagicLampData getInstance()
+ {
+ return Singleton.INSTANCE;
+ }
+
+ private static class Singleton
+ {
+ protected static final MagicLampData INSTANCE = new MagicLampData();
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/enums/LampMode.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/enums/LampMode.java
new file mode 100644
index 0000000000..a15d2fbcdf
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/enums/LampMode.java
@@ -0,0 +1,33 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.enums;
+
+import java.util.Arrays;
+
+/**
+ * @author L2CCCP
+ */
+public enum LampMode
+{
+ NORMAL,
+ GREATER;
+
+ public static LampMode getByMode(byte mode)
+ {
+ return Arrays.stream(values()).filter(type -> type.ordinal() == mode).findAny().orElse(NORMAL);
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/enums/LampType.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/enums/LampType.java
new file mode 100644
index 0000000000..716d5720ca
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/enums/LampType.java
@@ -0,0 +1,40 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.enums;
+
+/**
+ * @author L2CCCP
+ */
+public enum LampType
+{
+ RED(1),
+ PURPLE(2),
+ BLUE(3),
+ GREEN(4);
+
+ private int _grade;
+
+ LampType(int grade)
+ {
+ _grade = grade;
+ }
+
+ public int getGrade()
+ {
+ return _grade;
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/Party.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/Party.java
index 805cfc2ea7..bf3f80ee0b 100644
--- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/Party.java
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/Party.java
@@ -34,6 +34,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.GameTimeController;
import org.l2jmobius.gameserver.data.ItemTable;
+import org.l2jmobius.gameserver.data.xml.MagicLampData;
import org.l2jmobius.gameserver.enums.PartyDistributionType;
import org.l2jmobius.gameserver.enums.StatusUpdateType;
import org.l2jmobius.gameserver.instancemanager.DuelManager;
@@ -895,6 +896,7 @@ public class Party extends AbstractPlayerGroup
}
member.updateVitalityPoints(target.getVitalityPoints(member.getLevel(), exp, target.isRaid()), true, false);
PcCafePointsManager.getInstance().givePcCafePoint(member, exp);
+ MagicLampData.getInstance().addLampExp(member, exp);
}
}
else
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/Attackable.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/Attackable.java
index 2da4c47b0a..119f08c920 100644
--- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/Attackable.java
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/Attackable.java
@@ -35,6 +35,7 @@ import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.data.EventDroplist;
import org.l2jmobius.gameserver.data.ItemTable;
+import org.l2jmobius.gameserver.data.xml.MagicLampData;
import org.l2jmobius.gameserver.enums.ChatType;
import org.l2jmobius.gameserver.enums.DropType;
import org.l2jmobius.gameserver.enums.ElementalType;
@@ -530,6 +531,7 @@ public class Attackable extends Npc
attacker.updateVitalityPoints(getVitalityPoints(attacker.getLevel(), exp, _isRaid), true, false);
}
PcCafePointsManager.getInstance().givePcCafePoint(attacker, exp);
+ MagicLampData.getInstance().addLampExp(attacker, exp);
}
}
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index c50718cb16..f0f42b2aad 100644
--- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -1216,6 +1216,26 @@ public class PlayerInstance extends Playable
getVariables().set(PlayerVariables.HAIR_ACCESSORY_VARIABLE_NAME, enabled);
}
+ public int getLampExp()
+ {
+ return getVariables().getInt(PlayerVariables.MAGIC_LAMP_EXP, 0);
+ }
+
+ public int getLampCount()
+ {
+ return getVariables().getInt(PlayerVariables.MAGIC_LAMP_COUNT, 0);
+ }
+
+ public void setLampExp(int exp)
+ {
+ getVariables().set(PlayerVariables.MAGIC_LAMP_EXP, exp);
+ }
+
+ public void setLampCount(int count)
+ {
+ getVariables().set(PlayerVariables.MAGIC_LAMP_COUNT, count);
+ }
+
/**
* @return the base PlayerTemplate link to the PlayerInstance.
*/
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/events/AbstractScript.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/events/AbstractScript.java
index d995ddc7a3..ac9b529a4c 100644
--- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/events/AbstractScript.java
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/events/AbstractScript.java
@@ -39,6 +39,7 @@ import org.l2jmobius.gameserver.GameTimeController;
import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.data.xml.DoorData;
+import org.l2jmobius.gameserver.data.xml.MagicLampData;
import org.l2jmobius.gameserver.data.xml.NpcData;
import org.l2jmobius.gameserver.enums.AttributeType;
import org.l2jmobius.gameserver.enums.Movie;
@@ -3069,6 +3070,7 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
}
player.addExpAndSp((long) player.getStat().getValue(Stat.EXPSP_RATE, (exp * Config.RATE_QUEST_REWARD_XP)), (int) player.getStat().getValue(Stat.EXPSP_RATE, (sp * Config.RATE_QUEST_REWARD_SP)));
PcCafePointsManager.getInstance().givePcCafePoint(player, (long) (exp * Config.RATE_QUEST_REWARD_XP));
+ MagicLampData.getInstance().addLampExp(player, exp);
}
/**
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/holders/GreaterMagicLampHolder.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/holders/GreaterMagicLampHolder.java
new file mode 100644
index 0000000000..15c0f6558d
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/holders/GreaterMagicLampHolder.java
@@ -0,0 +1,44 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.model.holders;
+
+import org.l2jmobius.gameserver.model.StatSet;
+
+/**
+ * @author L2CCCP
+ */
+public class GreaterMagicLampHolder
+{
+ private final int _itemId;
+ private final long _count;
+
+ public GreaterMagicLampHolder(StatSet params)
+ {
+ _itemId = params.getInt("item");
+ _count = params.getLong("count");
+ }
+
+ public int getItemId()
+ {
+ return _itemId;
+ }
+
+ public long getCount()
+ {
+ return _count;
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/holders/MagicLampDataHolder.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/holders/MagicLampDataHolder.java
new file mode 100644
index 0000000000..53ae826abe
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/holders/MagicLampDataHolder.java
@@ -0,0 +1,67 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.model.holders;
+
+import org.l2jmobius.gameserver.enums.LampMode;
+import org.l2jmobius.gameserver.enums.LampType;
+import org.l2jmobius.gameserver.model.StatSet;
+
+/**
+ * @author L2CCCP
+ */
+public class MagicLampDataHolder
+{
+ private final LampMode _mode;
+ private final LampType _type;
+ private final long _exp;
+ private final long _sp;
+ private final double _chance;
+
+ public MagicLampDataHolder(StatSet params)
+ {
+ _mode = params.getEnum("mode", LampMode.class);
+ _type = params.getEnum("type", LampType.class);
+ _exp = params.getLong("exp");
+ _sp = params.getLong("sp");
+ _chance = params.getDouble("chance");
+ }
+
+ public LampMode getMode()
+ {
+ return _mode;
+ }
+
+ public LampType getType()
+ {
+ return _type;
+ }
+
+ public long getExp()
+ {
+ return _exp;
+ }
+
+ public long getSp()
+ {
+ return _sp;
+ }
+
+ public double getChance()
+ {
+ return _chance;
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/holders/MagicLampHolder.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/holders/MagicLampHolder.java
new file mode 100644
index 0000000000..2fbb3b0209
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/holders/MagicLampHolder.java
@@ -0,0 +1,62 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.model.holders;
+
+import org.l2jmobius.gameserver.enums.LampType;
+
+/**
+ * @author L2CCCP
+ */
+public class MagicLampHolder
+{
+ private final MagicLampDataHolder _lamp;
+ private int _count;
+ private long _exp;
+ private long _sp;
+
+ public MagicLampHolder(MagicLampDataHolder lamp)
+ {
+ _lamp = lamp;
+ }
+
+ public void inc()
+ {
+ _count++;
+ _exp += _lamp.getExp();
+ _sp += _lamp.getSp();
+ }
+
+ public LampType getType()
+ {
+ return _lamp.getType();
+ }
+
+ public int getCount()
+ {
+ return _count;
+ }
+
+ public long getExp()
+ {
+ return _exp;
+ }
+
+ public long getSp()
+ {
+ return _sp;
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java
index dadcce24e0..0e16a2a1cf 100644
--- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java
@@ -65,7 +65,10 @@ public class PlayerVariables extends AbstractVariables
public static final String HUNTING_ZONE_RESET_TIME = "HUNTING_ZONE_RESET_TIME_";
public static final String SAYHA_GRACE_SUPPORT_ENDTIME = "SAYHA_GRACE_SUPPORT_ENDTIME";
public static final String LIMITED_SAYHA_GRACE_ENDTIME = "LIMITED_SAYHA_GRACE_ENDTIME";
+ public static final String MAGIC_LAMP_EXP = "MAGIC_LAMP_EXP";
+ public static final String MAGIC_LAMP_COUNT = "MAGIC_LAMP_COUNT";
public static final String DEATH_POINT_COUNT = "DEATH_POINT_COUNT";
+ public static final String FAVORITE_TELEPORTS = "FAVORITE_TELEPORTS";
public static final String STAT_POINTS = "STAT_POINTS";
public static final String STAT_STR = "STAT_STR";
public static final String STAT_DEX = "STAT_DEX";
@@ -73,7 +76,6 @@ public class PlayerVariables extends AbstractVariables
public static final String STAT_INT = "STAT_INT";
public static final String STAT_WIT = "STAT_WIT";
public static final String STAT_MEN = "STAT_MEN";
- public static final String FAVORITE_TELEPORTS = "FAVORITE_TELEPORTS";
private final int _objectId;
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
index 16871335cc..f065c45ae9 100644
--- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
@@ -81,6 +81,8 @@ import org.l2jmobius.gameserver.network.clientpackets.limitshop.RequestPurchaseL
import org.l2jmobius.gameserver.network.clientpackets.limitshop.RequestPurchaseLimitShopItemList;
import org.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGamePlay;
import org.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGameStartInfo;
+import org.l2jmobius.gameserver.network.clientpackets.magiclamp.ExMagicLampGameInfo;
+import org.l2jmobius.gameserver.network.clientpackets.magiclamp.ExMagicLampGameStart;
import org.l2jmobius.gameserver.network.clientpackets.mentoring.ConfirmMenteeAdd;
import org.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeAdd;
import org.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeWaitingList;
@@ -491,8 +493,8 @@ public enum ExIncomingPackets implements IIncomingPackets
EX_COSTUME_EXTRACT(0x16C, null, ConnectionState.IN_GAME),
EX_COSTUME_LOCK(0x16D, null, ConnectionState.IN_GAME),
EX_COSTUME_CHANGE_SHORTCUT(0x16E, null, ConnectionState.IN_GAME),
- EX_MAGICLAMP_GAME_INFO(0x16F, null, ConnectionState.IN_GAME),
- EX_MAGICLAMP_GAME_START(0x170, null, ConnectionState.IN_GAME),
+ EX_MAGICLAMP_GAME_INFO(0x16F, ExMagicLampGameInfo::new, ConnectionState.IN_GAME),
+ EX_MAGICLAMP_GAME_START(0x170, ExMagicLampGameStart::new, ConnectionState.IN_GAME),
EX_ACTIVATE_AUTO_SHORTCUT(0x171, ExRequestActivateAutoShortcut::new, ConnectionState.IN_GAME),
EX_PREMIUM_MANAGER_LINK_HTML(0x172, null, ConnectionState.IN_GAME),
EX_PREMIUM_MANAGER_PASS_CMD_TO_SERVER(0x173, null, ConnectionState.IN_GAME),
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index 82d6897304..5811776dff 100644
--- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -108,6 +108,7 @@ import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExConnectedTi
import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList;
import org.l2jmobius.gameserver.network.serverpackets.friend.L2FriendList;
import org.l2jmobius.gameserver.network.serverpackets.limitshop.ExBloodyCoinCount;
+import org.l2jmobius.gameserver.network.serverpackets.magiclamp.ExMagicLampExpInfoUI;
import org.l2jmobius.gameserver.util.BuilderUtil;
/**
@@ -632,6 +633,11 @@ public class EnterWorld implements IClientIncomingPacket
player.sendPacket(new ExConnectedTimeAndGettableReward(player));
player.sendPacket(new ExOneDayReceiveRewardList(player, true));
+ if (Config.MAGIC_LAMP_ENABLE)
+ {
+ player.sendPacket(new ExMagicLampExpInfoUI(player));
+ }
+
// Handle soulshots, disable all on EnterWorld
player.sendPacket(new ExAutoSoulShot(0, true, 0));
player.sendPacket(new ExAutoSoulShot(0, true, 1));
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/magiclamp/ExMagicLampGameInfo.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/magiclamp/ExMagicLampGameInfo.java
new file mode 100644
index 0000000000..a0f5ffff54
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/magiclamp/ExMagicLampGameInfo.java
@@ -0,0 +1,50 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.network.clientpackets.magiclamp;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.magiclamp.ExMagicLampGameInfoUI;
+
+/**
+ * @author L2CCCP
+ */
+public class ExMagicLampGameInfo implements IClientIncomingPacket
+{
+ private byte _mode;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _mode = (byte) packet.readC(); // cGameMode
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final PlayerInstance player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ player.sendPacket(new ExMagicLampGameInfoUI(player, _mode, 1));
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/magiclamp/ExMagicLampGameStart.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/magiclamp/ExMagicLampGameStart.java
new file mode 100644
index 0000000000..7ad2bb0199
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/magiclamp/ExMagicLampGameStart.java
@@ -0,0 +1,52 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.network.clientpackets.magiclamp;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.magiclamp.ExMagicLampGameResult;
+
+/**
+ * @author L2CCCP
+ */
+public class ExMagicLampGameStart implements IClientIncomingPacket
+{
+ private int _count;
+ private byte _mode;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _count = packet.readD(); // nMagicLampGameCCount
+ _mode = (byte) packet.readC(); // cGameMode
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final PlayerInstance player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ client.sendPacket(new ExMagicLampGameResult(player, _count, _mode));
+ }
+}
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/serverpackets/magiclamp/ExMagicLampExpInfoUI.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/serverpackets/magiclamp/ExMagicLampExpInfoUI.java
new file mode 100644
index 0000000000..8b0d75ff4b
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/serverpackets/magiclamp/ExMagicLampExpInfoUI.java
@@ -0,0 +1,47 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.network.serverpackets.magiclamp;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author L2CCCP
+ */
+public class ExMagicLampExpInfoUI implements IClientOutgoingPacket
+{
+ private final PlayerInstance _player;
+
+ public ExMagicLampExpInfoUI(PlayerInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_MAGICLAMP_EXP_INFO.writeId(packet);
+ packet.writeD(Config.MAGIC_LAMP_ENABLE ? 0x01 : 0x00); // IsOpen
+ packet.writeD(Config.MAGIC_LAMP_MAX_LEVEL_EXP); // MaxMagicLampExp
+ packet.writeD(_player.getLampExp()); // MagicLampExp
+ packet.writeD(_player.getLampCount()); // MagicLampCount
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/serverpackets/magiclamp/ExMagicLampGameInfoUI.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/serverpackets/magiclamp/ExMagicLampGameInfoUI.java
new file mode 100644
index 0000000000..8964f48e29
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/serverpackets/magiclamp/ExMagicLampGameInfoUI.java
@@ -0,0 +1,77 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.network.serverpackets.magiclamp;
+
+import java.util.List;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.data.xml.MagicLampData;
+import org.l2jmobius.gameserver.enums.LampMode;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.GreaterMagicLampHolder;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author L2CCCP
+ */
+public class ExMagicLampGameInfoUI implements IClientOutgoingPacket
+{
+ private final PlayerInstance _player;
+ private final byte _mode;
+ private final int _count;
+
+ public ExMagicLampGameInfoUI(PlayerInstance player, byte mode, int count)
+ {
+ _player = player;
+ _mode = mode;
+ _count = count;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_MAGICLAMP_GAME_INFO.writeId(packet);
+ packet.writeD(Config.MAGIC_LAMP_MAX_GAME_COUNT); // nMagicLampGameMaxCCount
+ packet.writeD(_count); // cMagicLampGameCCount
+ switch (LampMode.getByMode(_mode))
+ {
+ case NORMAL:
+ {
+ packet.writeD(Config.MAGIC_LAMP_REWARD_COUNT);// cMagicLampCountPerGame
+ break;
+ }
+ case GREATER:
+ {
+ packet.writeD(Config.MAGIC_LAMP_GREATER_REWARD_COUNT); // cMagicLampCountPerGame
+ break;
+ }
+ }
+ packet.writeD(_player.getLampCount()); // cMagicLampCount
+ packet.writeC(_mode); // cGameMode
+ final List greater = MagicLampData.getInstance().getGreaterLamps();
+ packet.writeD(greater.size()); // costItemList
+ greater.forEach(lamp ->
+ {
+ packet.writeD(lamp.getItemId()); // nItemClassID
+ packet.writeQ(lamp.getCount()); // nItemAmountPerGame
+ packet.writeQ(_player.getInventory().getInventoryItemCount(lamp.getItemId(), -1)); // nItemAmount
+ });
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/serverpackets/magiclamp/ExMagicLampGameResult.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/serverpackets/magiclamp/ExMagicLampGameResult.java
new file mode 100644
index 0000000000..7d90f6dcbf
--- /dev/null
+++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/serverpackets/magiclamp/ExMagicLampGameResult.java
@@ -0,0 +1,124 @@
+/*
+ * 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 .
+ */
+package org.l2jmobius.gameserver.network.serverpackets.magiclamp;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.data.xml.MagicLampData;
+import org.l2jmobius.gameserver.enums.LampMode;
+import org.l2jmobius.gameserver.enums.LampType;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.MagicLampDataHolder;
+import org.l2jmobius.gameserver.model.holders.MagicLampHolder;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author L2CCCP
+ */
+public class ExMagicLampGameResult implements IClientOutgoingPacket
+{
+ private final Map _reward = new HashMap<>();
+
+ public ExMagicLampGameResult(PlayerInstance player, int count, byte mode)
+ {
+ final LampMode type = LampMode.getByMode(mode);
+ final int consume = calcConsume(type, count);
+ final int have = player.getLampCount();
+ if (have >= consume)
+ {
+ init(type, count);
+ player.setLampCount(have - consume);
+ _reward.values().forEach(lamp -> player.addExpAndSp(lamp.getExp(), lamp.getSp()));
+ // update UI
+ final int left = player.getLampCount();
+ player.sendPacket(new ExMagicLampGameInfoUI(player, mode, left > consume ? count : left)); // check left count for update UI
+ player.sendPacket(new ExMagicLampExpInfoUI(player));
+ }
+ }
+
+ private void init(LampMode mode, int count)
+ {
+ for (int x = count; x > 0; x--)
+ {
+ final List available = MagicLampData.getInstance().getLamps().stream().filter(lamp -> (lamp.getMode() == mode) && chance(lamp.getChance())).collect(Collectors.toList());
+ final MagicLampDataHolder random = getRandom(available);
+ if (random != null)
+ {
+ _reward.computeIfAbsent(random.getType(), list -> new MagicLampHolder(random)).inc();
+ }
+ }
+ }
+
+ private boolean chance(double chance)
+ {
+ return (chance > 0) && ((chance >= 100) || (Rnd.get(100d) <= chance));
+ }
+
+ private E getRandom(List list)
+ {
+ if (list.isEmpty())
+ {
+ return null;
+ }
+ if (list.size() == 1)
+ {
+ return list.get(0);
+ }
+ return list.get(Rnd.get(list.size()));
+ }
+
+ private int calcConsume(LampMode mode, int count)
+ {
+ switch (mode)
+ {
+ case NORMAL:
+ {
+ return Config.MAGIC_LAMP_REWARD_COUNT * count;
+ }
+ case GREATER:
+ {
+ return Config.MAGIC_LAMP_GREATER_REWARD_COUNT * count;
+ }
+ default:
+ {
+ return 0;
+ }
+ }
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_MAGICLAMP_GAME_RESULT.writeId(packet);
+ packet.writeD(_reward.size()); // magicLampGameResult
+ _reward.values().forEach(lamp ->
+ {
+ packet.writeC(lamp.getType().getGrade()); // cGradeNum
+ packet.writeD(lamp.getCount()); // nRewardCount
+ packet.writeQ(lamp.getExp()); // nEXP
+ packet.writeQ(lamp.getSp()); // nSP
+ });
+ return true;
+ }
+}
\ No newline at end of file