diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/LuckyGameData.xml b/L2J_Mobius_1.0_Ertheia/dist/game/data/LuckyGameData.xml index c65bb0fff5..b5e8885415 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/LuckyGameData.xml +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/LuckyGameData.xml @@ -1,225 +1,149 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java index 9b806fdb97..d121a6c06f 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java @@ -17,6 +17,7 @@ package events.EveTheFortuneTeller; import com.l2jmobius.gameserver.enums.ChatType; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.model.Location; import com.l2jmobius.gameserver.model.actor.L2Npc; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; @@ -36,6 +37,9 @@ public final class EveTheFortuneTeller extends LongTimeEvent // NPCs private static final int EVE = 8542; private static final int JAYCE = 8540; + // Items + private static final int FORTUNE_READING_TICKET = 23767; + private static final int LUXURY_FORTUNE_READING_TICKET = 23768; // Misc private static final Location JAYCE_SPAWN = new Location(148090, 26644, -2209, 16383); private static final NpcStringId[] JAYCE_TEXT = @@ -71,12 +75,12 @@ public final class EveTheFortuneTeller extends LongTimeEvent } case "FortuneReadingGame": { - player.sendPacket(new ExStartLuckyGame(player, 1)); + player.sendPacket(new ExStartLuckyGame(LuckyGameType.NORMAL, player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1))); break; } case "LuxuryFortuneReadingGame": { - player.sendPacket(new ExStartLuckyGame(player, 2)); + player.sendPacket(new ExStartLuckyGame(LuckyGameType.LUXURY, player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1))); break; } case "JAYCE_SHOUT": diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/LuckyGameData.xsd b/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/LuckyGameData.xsd index 95f23b1e7f..17e958d81f 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/LuckyGameData.xsd +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/LuckyGameData.xsd @@ -2,56 +2,68 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java index 02d7243e5c..d732ccb769 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java @@ -17,25 +17,26 @@ package com.l2jmobius.gameserver.data.xml.impl; import java.io.File; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; import com.l2jmobius.commons.util.IGameXmlReader; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemPointHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; /** - * @author Mathael + * @author Sdw */ public class LuckyGameData implements IGameXmlReader { - private static final List _fortuneReadingTicketRewards = new ArrayList<>(); - private static final List _luxuryFortuneReadingTicketRewards = new ArrayList<>(); - private static final List _rareLuxuryFortuneReadingTicketRewards = new ArrayList<>(); + private final Map _luckyGame = new HashMap<>(); + + final AtomicInteger _serverPlay = new AtomicInteger(); protected LuckyGameData() { @@ -45,112 +46,62 @@ public class LuckyGameData implements IGameXmlReader @Override public void load() { - _fortuneReadingTicketRewards.clear(); - _luxuryFortuneReadingTicketRewards.clear(); - _rareLuxuryFortuneReadingTicketRewards.clear(); - + _luckyGame.clear(); parseDatapackFile("data/LuckyGameData.xml"); - - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fortuneReadingTicketRewards.size() + " Normal item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luxuryFortuneReadingTicketRewards.size() + " Luxury item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rareLuxuryFortuneReadingTicketRewards.size() + " Rare item rewards."); + LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luckyGame.size() + " lucky game data."); } @Override public void parseDocument(Document doc, File f) { - for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) + forEach(doc, "list", listNode -> forEach(listNode, "luckygame", rewardNode -> { - if ("list".equalsIgnoreCase(n.getNodeName())) + final LuckyGameDataHolder holder = new LuckyGameDataHolder(new StatsSet(parseAttributes(rewardNode))); + + forEach(rewardNode, "common_reward", commonRewardNode -> forEach(commonRewardNode, "item", itemNode -> { - final NamedNodeMap at = n.getAttributes(); - final Node attribute = at.getNamedItem("enabled"); - if ((attribute != null) && Boolean.parseBoolean(attribute.getNodeValue())) // forEach(uniqueRewardNode, "item", itemNode -> + { + holder.addUniqueReward(new ItemPointHolder(new StatsSet(parseAttributes(itemNode)))); + })); + + forEach(rewardNode, "modify_reward", uniqueRewardNode -> + { + holder.setMinModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "min_game")); + holder.setMaxModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "max_game")); + forEach(uniqueRewardNode, "item", itemNode -> { - for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) - { - if ("fortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _fortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("luxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _luxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("rareLuxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _rareLuxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - } - } - } - } + final StatsSet stats = new StatsSet(parseAttributes(itemNode)); + holder.addModifyReward(new ItemChanceHolder(stats.getInt("id"), stats.getDouble("chance"), stats.getLong("count"))); + }); + }); + + _luckyGame.put(parseInteger(rewardNode.getAttributes(), "index"), holder); + })); } - public static ItemHolder getRandomNormalReward() + public int getLuckyGameCount() { - return _fortuneReadingTicketRewards.get(Rnd.get(_fortuneReadingTicketRewards.size())); + return _luckyGame.size(); } - public static ItemHolder getRandomLuxuryReward() + public LuckyGameDataHolder getLuckyGameDataByIndex(int index) { - return _luxuryFortuneReadingTicketRewards.get(Rnd.get(_luxuryFortuneReadingTicketRewards.size())); + return _luckyGame.get(index); } - public static ItemHolder getRandomRareReward() + public int increaseGame() { - return _rareLuxuryFortuneReadingTicketRewards.get(Rnd.get(_rareLuxuryFortuneReadingTicketRewards.size())); + return _serverPlay.incrementAndGet(); + } + + public int getServerPlay() + { + return _serverPlay.get(); } public static LuckyGameData getInstance() diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java new file mode 100644 index 0000000000..af1d82c1e1 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameItemType +{ + COMMON(1), + UNIQUE(2), + RARE(3); + + private final int _clientId; + + LuckyGameItemType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java new file mode 100644 index 0000000000..5a974d05d0 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameResultType +{ + INVALID_CAPACITY(-2), + INVALID_ITEM_COUNT(-1), + DISABLED(0), + SUCCESS(1); + + private final int _clientId; + + private LuckyGameResultType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/enums/LuckyGameType.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/enums/LuckyGameType.java new file mode 100644 index 0000000000..f8f7938727 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/enums/LuckyGameType.java @@ -0,0 +1,27 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameType +{ + NONE, + NORMAL, + LUXURY +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java new file mode 100644 index 0000000000..5d2fbfb7b8 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java @@ -0,0 +1,53 @@ +/* + * 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 com.l2jmobius.gameserver.model.holders; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class ItemPointHolder extends ItemHolder +{ + private final int _points; + + public ItemPointHolder(StatsSet params) + { + this(params.getInt("id"), params.getLong("count"), params.getInt("points")); + } + + public ItemPointHolder(int id, long count, int points) + { + super(id, count); + _points = points; + } + + /** + * Gets the point. + * @return the number of point to get the item + */ + public int getPoints() + { + return _points; + } + + @Override + public String toString() + { + return "[" + getClass().getSimpleName() + "] ID: " + getId() + ", count: " + getCount() + ", points: " + _points; + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java new file mode 100644 index 0000000000..43e93e30c5 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java @@ -0,0 +1,102 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.model.holders; + +import java.util.ArrayList; +import java.util.List; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class LuckyGameDataHolder +{ + final private int _index; + final private int _turningPoints; + final private List _commonRewards = new ArrayList<>(); + final private List _uniqueRewards = new ArrayList<>(); + final private List _modifyRewards = new ArrayList<>(); + private int _minModifyRewardGame; + private int _maxModifyRewardGame; + + public LuckyGameDataHolder(StatsSet params) + { + _index = params.getInt("index"); + _turningPoints = params.getInt("turning_point"); + } + + public void addCommonReward(ItemChanceHolder item) + { + _commonRewards.add(item); + } + + public void addUniqueReward(ItemPointHolder item) + { + _uniqueRewards.add(item); + } + + public void addModifyReward(ItemChanceHolder item) + { + _modifyRewards.add(item); + } + + public List getCommonReward() + { + return _commonRewards; + } + + public List getUniqueReward() + { + return _uniqueRewards; + } + + public List getModifyReward() + { + return _modifyRewards; + } + + public void setMinModifyRewardGame(int minModifyRewardGame) + { + _minModifyRewardGame = minModifyRewardGame; + } + + public void setMaxModifyRewardGame(int maxModifyRewardGame) + { + _maxModifyRewardGame = maxModifyRewardGame; + } + + public int getMinModifyRewardGame() + { + return _minModifyRewardGame; + } + + public int getMaxModifyRewardGame() + { + return _maxModifyRewardGame; + } + + public int getIndex() + { + return _index; + } + + public int getTurningPoints() + { + return _turningPoints; + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java index accf605dd6..9642df097c 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java @@ -57,6 +57,8 @@ public class PlayerVariables extends AbstractVariables public static final String REVELATION_SKILL_1_DUAL_CLASS = "DualclassRevelationSkill1"; public static final String REVELATION_SKILL_2_DUAL_CLASS = "DualclassRevelationSkill2"; public static final String EXTEND_DROP = "EXTEND_DROP"; + public static final String FORTUNE_TELLING_VARIABLE = "FortuneTelling"; + public static final String FORTUNE_TELLING_BLACK_CAT_VARIABLE = "FortuneTellingBlackCat"; private final int _objectId; diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index 50a5cfcff4..c9e345138a 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -65,6 +65,8 @@ import com.l2jmobius.gameserver.network.clientpackets.compound.RequestNewEnchant import com.l2jmobius.gameserver.network.clientpackets.crystalization.RequestCrystallizeEstimate; import com.l2jmobius.gameserver.network.clientpackets.crystalization.RequestCrystallizeItemCancel; import com.l2jmobius.gameserver.network.clientpackets.friend.RequestFriendDetailInfo; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGamePlay; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGameStartInfo; import com.l2jmobius.gameserver.network.clientpackets.mentoring.ConfirmMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeWaitingList; @@ -322,8 +324,8 @@ public enum ExIncomingPackets implements IIncomingPackets REQUEST_ABILITY_WND_OPEN(0xEE, RequestAbilityWndOpen::new, ConnectionState.IN_GAME), REQUEST_ABILITY_WND_CLOSE(0xEF, RequestAbilityWndClose::new, ConnectionState.IN_GAME), EX_PC_CAFE_REQUEST_OPEN_WINDOW_WITHOUT_NPC(0xF0, ExPCCafeRequestOpenWindowWithoutNPC::new, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_START_INFO(0xF1, null, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_PLAY(0xF2, null, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_START_INFO(0xF1, RequestLuckyGameStartInfo::new, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_PLAY(0xF2, RequestLuckyGamePlay::new, ConnectionState.IN_GAME), NOTIFY_TRAINING_ROOM_END(0xF3, null, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_PUSH_ONE(0xF4, RequestNewEnchantPushOne::new, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_REMOVE_ONE(0xF5, RequestNewEnchantRemoveOne::new, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java index 72f40dcba6..1e48d2cfb6 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java @@ -16,30 +16,169 @@ */ package com.l2jmobius.gameserver.network.clientpackets.luckygame; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map.Entry; + import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.commons.util.CommonUtil; +import com.l2jmobius.commons.util.Rnd; +import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; +import com.l2jmobius.gameserver.datatables.ItemTable; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; +import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; +import com.l2jmobius.gameserver.model.variables.PlayerVariables; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; +import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; import com.l2jmobius.gameserver.network.serverpackets.luckygame.ExBettingLuckyGameResult; /** - * @author Mobius + * @author Sdw */ public class RequestLuckyGamePlay implements IClientIncomingPacket { - private int _type; - private int _count; + private static final int FORTUNE_READING_TICKET = 23767; + private static final int LUXURY_FORTUNE_READING_TICKET = 23768; + private LuckyGameType _type; + private int _reading; @Override public boolean read(L2GameClient client, PacketReader packet) { - _type = packet.readD(); // luxury = 2, normal = 1 - _count = packet.readD(); // count + final int type = CommonUtil.constrain(packet.readD(), 0, LuckyGameType.values().length); + _type = LuckyGameType.values()[type]; + _reading = CommonUtil.constrain(packet.readD(), 0, 50); // max play is 50 return true; } @Override public void run(L2GameClient client) { - client.getActiveChar().sendPacket(new ExBettingLuckyGameResult(client.getActiveChar(), _type, _count)); + final L2PcInstance player = client.getActiveChar(); + if (player == null) + { + return; + } + + final int index = _type == LuckyGameType.LUXURY ? 102 : 2; // move to event config + + final LuckyGameDataHolder holder = LuckyGameData.getInstance().getLuckyGameDataByIndex(index); + if (holder == null) + { + return; + } + + final long tickets = _type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1); + if (tickets < _reading) + { + player.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + int playCount = player.getVariables().getInt(PlayerVariables.FORTUNE_TELLING_VARIABLE, 0); + boolean blackCat = player.getVariables().getBoolean(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, false); + final EnumMap> rewards = new EnumMap<>(LuckyGameItemType.class); + for (int i = 0; i < _reading; i++) + { + final double chance = 100 * Rnd.nextDouble(); + double totalChance = 0; + + for (ItemChanceHolder item : holder.getCommonReward()) + { + totalChance += item.getChance(); + if (totalChance >= chance) + { + rewards.computeIfAbsent(LuckyGameItemType.COMMON, k -> new ArrayList<>()).add(item); + break; + } + } + playCount++; + if ((playCount >= holder.getMinModifyRewardGame()) && (playCount <= holder.getMaxModifyRewardGame()) && !blackCat) + { + final List modifyReward = holder.getModifyReward(); + final double chanceModify = 100 * Rnd.nextDouble(); + totalChance = 0; + + for (ItemChanceHolder item : modifyReward) + { + totalChance += item.getChance(); + if (totalChance >= chanceModify) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(item); + blackCat = true; + break; + } + } + + if (playCount == holder.getMaxModifyRewardGame()) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(modifyReward.get(Rnd.get(modifyReward.size()))); + blackCat = true; + } + } + } + + final int totalWeight = rewards.values().stream().mapToInt(list -> list.stream().mapToInt(item -> ItemTable.getInstance().getTemplate(item.getId()).getWeight()).sum()).sum(); + + // Check inventory capacity + if ((rewards.size() > 0) && (!player.getInventory().validateCapacity(rewards.size()) || !player.getInventory().validateWeight(totalWeight))) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_CAPACITY : ExBettingLuckyGameResult.NORMAL_INVALID_CAPACITY); + player.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); + return; + } + + if (!player.destroyItemByItemId("LuckyGame", _type == LuckyGameType.LUXURY ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _reading, player, true)) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + for (int i = 0; i < _reading; i++) + { + final int serverGameNumber = LuckyGameData.getInstance().increaseGame(); + holder.getUniqueReward().stream().filter(reward -> reward.getPoints() == serverGameNumber).forEach(item -> rewards.computeIfAbsent(LuckyGameItemType.UNIQUE, k -> new ArrayList<>()).add(item)); + } + + player.sendPacket(new ExBettingLuckyGameResult(LuckyGameResultType.SUCCESS, _type, rewards, (int) (_type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1)))); + + final InventoryUpdate iu = new InventoryUpdate(); + for (Entry> reward : rewards.entrySet()) + { + for (ItemHolder r : reward.getValue()) + { + final L2ItemInstance item = player.addItem("LuckyGame", r.getId(), r.getCount(), player, true); + iu.addItem(item); + if (reward.getKey() == LuckyGameItemType.UNIQUE) + { + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); + sm.addPcName(player); + sm.addLong(r.getCount()); + sm.addItemName(item); + player.broadcastPacket(sm, 1000); + break; + } + + } + } + + player.sendInventoryUpdate(iu); + + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_VARIABLE, playCount >= 50 ? (playCount - 50) : playCount); + if (blackCat && (playCount < 50)) + { + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, true); + } } } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java new file mode 100644 index 0000000000..e39f110a76 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.network.clientpackets.luckygame; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; + +/** + * @author Sdw + */ +public class RequestLuckyGameStartInfo implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return true; + } + + @Override + public void run(L2GameClient client) + { + + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java index 32d7ebc372..d36f6bb0c3 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java @@ -16,121 +16,69 @@ */ package com.l2jmobius.gameserver.network.serverpackets.luckygame; -import java.util.ArrayList; +import java.util.EnumMap; import java.util.List; +import java.util.Map.Entry; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.model.holders.ItemHolder; -import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.network.OutgoingPackets; -import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; -import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** - * @author Mobius + * @author Sdw */ public class ExBettingLuckyGameResult implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _count = 0; - private int _type = 0; - private final L2PcInstance _activeChar; + public static final ExBettingLuckyGameResult NORMAL_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.LUXURY); + public static final ExBettingLuckyGameResult NORMAL_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.LUXURY); - public ExBettingLuckyGameResult(L2PcInstance activeChar, int type, int count) + private final LuckyGameResultType _result; + private final LuckyGameType _type; + private final EnumMap> _rewards; + private final int _ticketCount; + private final int _size; + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type) { - _count = count; + _result = result; _type = type; - _activeChar = activeChar; + _rewards = new EnumMap<>(LuckyGameItemType.class); + _ticketCount = 0; + _size = 0; + } + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type, EnumMap> rewards, int ticketCount) + { + _result = result; + _type = type; + _rewards = rewards; + _ticketCount = ticketCount; + _size = (int) rewards.values().stream().mapToLong(i -> i.stream().count()).sum(); } @Override public boolean write(PacketWriter packet) { - // Calculate rewards - final List rewards = new ArrayList<>(); - int totalWeight = 0; - for (int rewardCounter = 0; rewardCounter < _count; rewardCounter++) - { - if (Rnd.get(3) == 0) // 1 out of 3 chance - { - ItemHolder reward = null; - if (_type == 2) - { - if (_count >= 40) - { - reward = LuckyGameData.getRandomRareReward(); - } - else - { - reward = LuckyGameData.getRandomLuxuryReward(); - } - } - else - { - reward = LuckyGameData.getRandomNormalReward(); - } - rewards.add(reward); - totalWeight += new L2ItemInstance(reward.getId()).getItem().getWeight() * reward.getCount(); - } - } - - // Check inventory capacity - if ((rewards.size() > 0) && (!_activeChar.getInventory().validateCapacity(rewards.size()) || !_activeChar.getInventory().validateWeight(totalWeight))) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); - return false; - } - - if (_activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1) < _count) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); - return false; - } - - // Remove tickets - _activeChar.getInventory().destroyItemByItemId("FortuneTelling", _type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _count, _activeChar, "FortuneTelling"); - OutgoingPackets.EX_BETTING_LUCKY_GAME_RESULT.writeId(packet); - packet.writeD(0x01); // 0 disabled, 1 enabled - packet.writeD(0x01); // ? - packet.writeD((int) _activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1)); // Count remaining tickets - - if (rewards.size() > 0) + packet.writeD(_result.getClientId()); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); + packet.writeD(_size); + for (Entry> reward : _rewards.entrySet()) { - packet.writeD(rewards.size()); - for (ItemHolder reward : rewards) + for (ItemHolder item : reward.getValue()) { - packet.writeD(0x02); // normal = 1, rare = 2 (forcing 2) - packet.writeD(reward.getId()); - packet.writeD((int) reward.getCount()); - final SystemMessage sm; - if (_type == 2) - { - _activeChar.addItem("LuxuryFortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_IN_THE_LUXURY_FORTUNE_READING); - } - else - { - _activeChar.addItem("FortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); - } - sm.addPcName(_activeChar); - sm.addLong(reward.getCount()); - sm.addItemName(new L2ItemInstance(reward.getId())); - _activeChar.broadcastPacket(sm, 1000); + packet.writeD(reward.getKey().getClientId()); + packet.writeD(item.getId()); + packet.writeD((int) item.getCount()); } } - else - { - packet.writeD(0x00); - } return true; } } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java index 4d58f5d294..233363fde2 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java @@ -17,32 +17,30 @@ package com.l2jmobius.gameserver.network.serverpackets.luckygame; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.network.OutgoingPackets; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; /** - * @author Mobius + * @author Sdw */ public class ExStartLuckyGame implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _type = 0; - private int _count = 0; + private final LuckyGameType _type; + private final int _ticketCount; - public ExStartLuckyGame(L2PcInstance activeChar, int type) + public ExStartLuckyGame(LuckyGameType type, long ticketCount) { _type = type; - _count = (int) activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1); + _ticketCount = (int) ticketCount; } @Override public boolean write(PacketWriter packet) { OutgoingPackets.EX_START_LUCKY_GAME.writeId(packet); - packet.writeD(_type); - packet.writeD(_count); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); return true; } } diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/LuckyGameData.xml b/L2J_Mobius_2.5_Underground/dist/game/data/LuckyGameData.xml index c65bb0fff5..595b4d47f0 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/LuckyGameData.xml +++ b/L2J_Mobius_2.5_Underground/dist/game/data/LuckyGameData.xml @@ -1,225 +1,224 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java index 9b806fdb97..d121a6c06f 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java @@ -17,6 +17,7 @@ package events.EveTheFortuneTeller; import com.l2jmobius.gameserver.enums.ChatType; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.model.Location; import com.l2jmobius.gameserver.model.actor.L2Npc; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; @@ -36,6 +37,9 @@ public final class EveTheFortuneTeller extends LongTimeEvent // NPCs private static final int EVE = 8542; private static final int JAYCE = 8540; + // Items + private static final int FORTUNE_READING_TICKET = 23767; + private static final int LUXURY_FORTUNE_READING_TICKET = 23768; // Misc private static final Location JAYCE_SPAWN = new Location(148090, 26644, -2209, 16383); private static final NpcStringId[] JAYCE_TEXT = @@ -71,12 +75,12 @@ public final class EveTheFortuneTeller extends LongTimeEvent } case "FortuneReadingGame": { - player.sendPacket(new ExStartLuckyGame(player, 1)); + player.sendPacket(new ExStartLuckyGame(LuckyGameType.NORMAL, player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1))); break; } case "LuxuryFortuneReadingGame": { - player.sendPacket(new ExStartLuckyGame(player, 2)); + player.sendPacket(new ExStartLuckyGame(LuckyGameType.LUXURY, player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1))); break; } case "JAYCE_SHOUT": diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/xsd/LuckyGameData.xsd b/L2J_Mobius_2.5_Underground/dist/game/data/xsd/LuckyGameData.xsd index 95f23b1e7f..17e958d81f 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/xsd/LuckyGameData.xsd +++ b/L2J_Mobius_2.5_Underground/dist/game/data/xsd/LuckyGameData.xsd @@ -2,56 +2,68 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java index 02d7243e5c..d732ccb769 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java @@ -17,25 +17,26 @@ package com.l2jmobius.gameserver.data.xml.impl; import java.io.File; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; import com.l2jmobius.commons.util.IGameXmlReader; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemPointHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; /** - * @author Mathael + * @author Sdw */ public class LuckyGameData implements IGameXmlReader { - private static final List _fortuneReadingTicketRewards = new ArrayList<>(); - private static final List _luxuryFortuneReadingTicketRewards = new ArrayList<>(); - private static final List _rareLuxuryFortuneReadingTicketRewards = new ArrayList<>(); + private final Map _luckyGame = new HashMap<>(); + + final AtomicInteger _serverPlay = new AtomicInteger(); protected LuckyGameData() { @@ -45,112 +46,62 @@ public class LuckyGameData implements IGameXmlReader @Override public void load() { - _fortuneReadingTicketRewards.clear(); - _luxuryFortuneReadingTicketRewards.clear(); - _rareLuxuryFortuneReadingTicketRewards.clear(); - + _luckyGame.clear(); parseDatapackFile("data/LuckyGameData.xml"); - - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fortuneReadingTicketRewards.size() + " Normal item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luxuryFortuneReadingTicketRewards.size() + " Luxury item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rareLuxuryFortuneReadingTicketRewards.size() + " Rare item rewards."); + LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luckyGame.size() + " lucky game data."); } @Override public void parseDocument(Document doc, File f) { - for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) + forEach(doc, "list", listNode -> forEach(listNode, "luckygame", rewardNode -> { - if ("list".equalsIgnoreCase(n.getNodeName())) + final LuckyGameDataHolder holder = new LuckyGameDataHolder(new StatsSet(parseAttributes(rewardNode))); + + forEach(rewardNode, "common_reward", commonRewardNode -> forEach(commonRewardNode, "item", itemNode -> { - final NamedNodeMap at = n.getAttributes(); - final Node attribute = at.getNamedItem("enabled"); - if ((attribute != null) && Boolean.parseBoolean(attribute.getNodeValue())) // forEach(uniqueRewardNode, "item", itemNode -> + { + holder.addUniqueReward(new ItemPointHolder(new StatsSet(parseAttributes(itemNode)))); + })); + + forEach(rewardNode, "modify_reward", uniqueRewardNode -> + { + holder.setMinModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "min_game")); + holder.setMaxModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "max_game")); + forEach(uniqueRewardNode, "item", itemNode -> { - for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) - { - if ("fortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _fortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("luxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _luxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("rareLuxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _rareLuxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - } - } - } - } + final StatsSet stats = new StatsSet(parseAttributes(itemNode)); + holder.addModifyReward(new ItemChanceHolder(stats.getInt("id"), stats.getDouble("chance"), stats.getLong("count"))); + }); + }); + + _luckyGame.put(parseInteger(rewardNode.getAttributes(), "index"), holder); + })); } - public static ItemHolder getRandomNormalReward() + public int getLuckyGameCount() { - return _fortuneReadingTicketRewards.get(Rnd.get(_fortuneReadingTicketRewards.size())); + return _luckyGame.size(); } - public static ItemHolder getRandomLuxuryReward() + public LuckyGameDataHolder getLuckyGameDataByIndex(int index) { - return _luxuryFortuneReadingTicketRewards.get(Rnd.get(_luxuryFortuneReadingTicketRewards.size())); + return _luckyGame.get(index); } - public static ItemHolder getRandomRareReward() + public int increaseGame() { - return _rareLuxuryFortuneReadingTicketRewards.get(Rnd.get(_rareLuxuryFortuneReadingTicketRewards.size())); + return _serverPlay.incrementAndGet(); + } + + public int getServerPlay() + { + return _serverPlay.get(); } public static LuckyGameData getInstance() diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java new file mode 100644 index 0000000000..af1d82c1e1 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameItemType +{ + COMMON(1), + UNIQUE(2), + RARE(3); + + private final int _clientId; + + LuckyGameItemType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java new file mode 100644 index 0000000000..5a974d05d0 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameResultType +{ + INVALID_CAPACITY(-2), + INVALID_ITEM_COUNT(-1), + DISABLED(0), + SUCCESS(1); + + private final int _clientId; + + private LuckyGameResultType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/enums/LuckyGameType.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/enums/LuckyGameType.java new file mode 100644 index 0000000000..f8f7938727 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/enums/LuckyGameType.java @@ -0,0 +1,27 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameType +{ + NONE, + NORMAL, + LUXURY +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java new file mode 100644 index 0000000000..5d2fbfb7b8 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java @@ -0,0 +1,53 @@ +/* + * 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 com.l2jmobius.gameserver.model.holders; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class ItemPointHolder extends ItemHolder +{ + private final int _points; + + public ItemPointHolder(StatsSet params) + { + this(params.getInt("id"), params.getLong("count"), params.getInt("points")); + } + + public ItemPointHolder(int id, long count, int points) + { + super(id, count); + _points = points; + } + + /** + * Gets the point. + * @return the number of point to get the item + */ + public int getPoints() + { + return _points; + } + + @Override + public String toString() + { + return "[" + getClass().getSimpleName() + "] ID: " + getId() + ", count: " + getCount() + ", points: " + _points; + } +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java new file mode 100644 index 0000000000..43e93e30c5 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java @@ -0,0 +1,102 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.model.holders; + +import java.util.ArrayList; +import java.util.List; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class LuckyGameDataHolder +{ + final private int _index; + final private int _turningPoints; + final private List _commonRewards = new ArrayList<>(); + final private List _uniqueRewards = new ArrayList<>(); + final private List _modifyRewards = new ArrayList<>(); + private int _minModifyRewardGame; + private int _maxModifyRewardGame; + + public LuckyGameDataHolder(StatsSet params) + { + _index = params.getInt("index"); + _turningPoints = params.getInt("turning_point"); + } + + public void addCommonReward(ItemChanceHolder item) + { + _commonRewards.add(item); + } + + public void addUniqueReward(ItemPointHolder item) + { + _uniqueRewards.add(item); + } + + public void addModifyReward(ItemChanceHolder item) + { + _modifyRewards.add(item); + } + + public List getCommonReward() + { + return _commonRewards; + } + + public List getUniqueReward() + { + return _uniqueRewards; + } + + public List getModifyReward() + { + return _modifyRewards; + } + + public void setMinModifyRewardGame(int minModifyRewardGame) + { + _minModifyRewardGame = minModifyRewardGame; + } + + public void setMaxModifyRewardGame(int maxModifyRewardGame) + { + _maxModifyRewardGame = maxModifyRewardGame; + } + + public int getMinModifyRewardGame() + { + return _minModifyRewardGame; + } + + public int getMaxModifyRewardGame() + { + return _maxModifyRewardGame; + } + + public int getIndex() + { + return _index; + } + + public int getTurningPoints() + { + return _turningPoints; + } +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java index 7698c1f912..fd1fb41f5f 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java @@ -57,6 +57,8 @@ public class PlayerVariables extends AbstractVariables public static final String REVELATION_SKILL_1_DUAL_CLASS = "DualclassRevelationSkill1"; public static final String REVELATION_SKILL_2_DUAL_CLASS = "DualclassRevelationSkill2"; public static final String EXTEND_DROP = "EXTEND_DROP"; + public static final String FORTUNE_TELLING_VARIABLE = "FortuneTelling"; + public static final String FORTUNE_TELLING_BLACK_CAT_VARIABLE = "FortuneTellingBlackCat"; private final int _objectId; diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index 602cfacc43..0f376d7f30 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -68,6 +68,8 @@ import com.l2jmobius.gameserver.network.clientpackets.dailymission.RequestOneDay import com.l2jmobius.gameserver.network.clientpackets.dailymission.RequestTodoList; import com.l2jmobius.gameserver.network.clientpackets.ensoul.RequestItemEnsoul; import com.l2jmobius.gameserver.network.clientpackets.friend.RequestFriendDetailInfo; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGamePlay; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGameStartInfo; import com.l2jmobius.gameserver.network.clientpackets.mentoring.ConfirmMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeWaitingList; @@ -328,8 +330,8 @@ public enum ExIncomingPackets implements IIncomingPackets REQUEST_ABILITY_WND_OPEN(0xEE, RequestAbilityWndOpen::new, ConnectionState.IN_GAME), REQUEST_ABILITY_WND_CLOSE(0xEF, RequestAbilityWndClose::new, ConnectionState.IN_GAME), EX_PC_CAFE_REQUEST_OPEN_WINDOW_WITHOUT_NPC(0xF0, ExPCCafeRequestOpenWindowWithoutNPC::new, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_START_INFO(0xF1, null, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_PLAY(0xF2, null, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_START_INFO(0xF1, RequestLuckyGameStartInfo::new, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_PLAY(0xF2, RequestLuckyGamePlay::new, ConnectionState.IN_GAME), NOTIFY_TRAINING_ROOM_END(0xF3, null, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_PUSH_ONE(0xF4, RequestNewEnchantPushOne::new, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_REMOVE_ONE(0xF5, RequestNewEnchantRemoveOne::new, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java index 72f40dcba6..1e48d2cfb6 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java @@ -16,30 +16,169 @@ */ package com.l2jmobius.gameserver.network.clientpackets.luckygame; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map.Entry; + import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.commons.util.CommonUtil; +import com.l2jmobius.commons.util.Rnd; +import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; +import com.l2jmobius.gameserver.datatables.ItemTable; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; +import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; +import com.l2jmobius.gameserver.model.variables.PlayerVariables; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; +import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; import com.l2jmobius.gameserver.network.serverpackets.luckygame.ExBettingLuckyGameResult; /** - * @author Mobius + * @author Sdw */ public class RequestLuckyGamePlay implements IClientIncomingPacket { - private int _type; - private int _count; + private static final int FORTUNE_READING_TICKET = 23767; + private static final int LUXURY_FORTUNE_READING_TICKET = 23768; + private LuckyGameType _type; + private int _reading; @Override public boolean read(L2GameClient client, PacketReader packet) { - _type = packet.readD(); // luxury = 2, normal = 1 - _count = packet.readD(); // count + final int type = CommonUtil.constrain(packet.readD(), 0, LuckyGameType.values().length); + _type = LuckyGameType.values()[type]; + _reading = CommonUtil.constrain(packet.readD(), 0, 50); // max play is 50 return true; } @Override public void run(L2GameClient client) { - client.getActiveChar().sendPacket(new ExBettingLuckyGameResult(client.getActiveChar(), _type, _count)); + final L2PcInstance player = client.getActiveChar(); + if (player == null) + { + return; + } + + final int index = _type == LuckyGameType.LUXURY ? 102 : 2; // move to event config + + final LuckyGameDataHolder holder = LuckyGameData.getInstance().getLuckyGameDataByIndex(index); + if (holder == null) + { + return; + } + + final long tickets = _type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1); + if (tickets < _reading) + { + player.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + int playCount = player.getVariables().getInt(PlayerVariables.FORTUNE_TELLING_VARIABLE, 0); + boolean blackCat = player.getVariables().getBoolean(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, false); + final EnumMap> rewards = new EnumMap<>(LuckyGameItemType.class); + for (int i = 0; i < _reading; i++) + { + final double chance = 100 * Rnd.nextDouble(); + double totalChance = 0; + + for (ItemChanceHolder item : holder.getCommonReward()) + { + totalChance += item.getChance(); + if (totalChance >= chance) + { + rewards.computeIfAbsent(LuckyGameItemType.COMMON, k -> new ArrayList<>()).add(item); + break; + } + } + playCount++; + if ((playCount >= holder.getMinModifyRewardGame()) && (playCount <= holder.getMaxModifyRewardGame()) && !blackCat) + { + final List modifyReward = holder.getModifyReward(); + final double chanceModify = 100 * Rnd.nextDouble(); + totalChance = 0; + + for (ItemChanceHolder item : modifyReward) + { + totalChance += item.getChance(); + if (totalChance >= chanceModify) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(item); + blackCat = true; + break; + } + } + + if (playCount == holder.getMaxModifyRewardGame()) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(modifyReward.get(Rnd.get(modifyReward.size()))); + blackCat = true; + } + } + } + + final int totalWeight = rewards.values().stream().mapToInt(list -> list.stream().mapToInt(item -> ItemTable.getInstance().getTemplate(item.getId()).getWeight()).sum()).sum(); + + // Check inventory capacity + if ((rewards.size() > 0) && (!player.getInventory().validateCapacity(rewards.size()) || !player.getInventory().validateWeight(totalWeight))) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_CAPACITY : ExBettingLuckyGameResult.NORMAL_INVALID_CAPACITY); + player.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); + return; + } + + if (!player.destroyItemByItemId("LuckyGame", _type == LuckyGameType.LUXURY ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _reading, player, true)) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + for (int i = 0; i < _reading; i++) + { + final int serverGameNumber = LuckyGameData.getInstance().increaseGame(); + holder.getUniqueReward().stream().filter(reward -> reward.getPoints() == serverGameNumber).forEach(item -> rewards.computeIfAbsent(LuckyGameItemType.UNIQUE, k -> new ArrayList<>()).add(item)); + } + + player.sendPacket(new ExBettingLuckyGameResult(LuckyGameResultType.SUCCESS, _type, rewards, (int) (_type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1)))); + + final InventoryUpdate iu = new InventoryUpdate(); + for (Entry> reward : rewards.entrySet()) + { + for (ItemHolder r : reward.getValue()) + { + final L2ItemInstance item = player.addItem("LuckyGame", r.getId(), r.getCount(), player, true); + iu.addItem(item); + if (reward.getKey() == LuckyGameItemType.UNIQUE) + { + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); + sm.addPcName(player); + sm.addLong(r.getCount()); + sm.addItemName(item); + player.broadcastPacket(sm, 1000); + break; + } + + } + } + + player.sendInventoryUpdate(iu); + + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_VARIABLE, playCount >= 50 ? (playCount - 50) : playCount); + if (blackCat && (playCount < 50)) + { + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, true); + } } } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java new file mode 100644 index 0000000000..e39f110a76 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.network.clientpackets.luckygame; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; + +/** + * @author Sdw + */ +public class RequestLuckyGameStartInfo implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return true; + } + + @Override + public void run(L2GameClient client) + { + + } +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java index 32d7ebc372..d36f6bb0c3 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java @@ -16,121 +16,69 @@ */ package com.l2jmobius.gameserver.network.serverpackets.luckygame; -import java.util.ArrayList; +import java.util.EnumMap; import java.util.List; +import java.util.Map.Entry; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.model.holders.ItemHolder; -import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.network.OutgoingPackets; -import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; -import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** - * @author Mobius + * @author Sdw */ public class ExBettingLuckyGameResult implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _count = 0; - private int _type = 0; - private final L2PcInstance _activeChar; + public static final ExBettingLuckyGameResult NORMAL_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.LUXURY); + public static final ExBettingLuckyGameResult NORMAL_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.LUXURY); - public ExBettingLuckyGameResult(L2PcInstance activeChar, int type, int count) + private final LuckyGameResultType _result; + private final LuckyGameType _type; + private final EnumMap> _rewards; + private final int _ticketCount; + private final int _size; + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type) { - _count = count; + _result = result; _type = type; - _activeChar = activeChar; + _rewards = new EnumMap<>(LuckyGameItemType.class); + _ticketCount = 0; + _size = 0; + } + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type, EnumMap> rewards, int ticketCount) + { + _result = result; + _type = type; + _rewards = rewards; + _ticketCount = ticketCount; + _size = (int) rewards.values().stream().mapToLong(i -> i.stream().count()).sum(); } @Override public boolean write(PacketWriter packet) { - // Calculate rewards - final List rewards = new ArrayList<>(); - int totalWeight = 0; - for (int rewardCounter = 0; rewardCounter < _count; rewardCounter++) - { - if (Rnd.get(3) == 0) // 1 out of 3 chance - { - ItemHolder reward = null; - if (_type == 2) - { - if (_count >= 40) - { - reward = LuckyGameData.getRandomRareReward(); - } - else - { - reward = LuckyGameData.getRandomLuxuryReward(); - } - } - else - { - reward = LuckyGameData.getRandomNormalReward(); - } - rewards.add(reward); - totalWeight += new L2ItemInstance(reward.getId()).getItem().getWeight() * reward.getCount(); - } - } - - // Check inventory capacity - if ((rewards.size() > 0) && (!_activeChar.getInventory().validateCapacity(rewards.size()) || !_activeChar.getInventory().validateWeight(totalWeight))) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); - return false; - } - - if (_activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1) < _count) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); - return false; - } - - // Remove tickets - _activeChar.getInventory().destroyItemByItemId("FortuneTelling", _type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _count, _activeChar, "FortuneTelling"); - OutgoingPackets.EX_BETTING_LUCKY_GAME_RESULT.writeId(packet); - packet.writeD(0x01); // 0 disabled, 1 enabled - packet.writeD(0x01); // ? - packet.writeD((int) _activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1)); // Count remaining tickets - - if (rewards.size() > 0) + packet.writeD(_result.getClientId()); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); + packet.writeD(_size); + for (Entry> reward : _rewards.entrySet()) { - packet.writeD(rewards.size()); - for (ItemHolder reward : rewards) + for (ItemHolder item : reward.getValue()) { - packet.writeD(0x02); // normal = 1, rare = 2 (forcing 2) - packet.writeD(reward.getId()); - packet.writeD((int) reward.getCount()); - final SystemMessage sm; - if (_type == 2) - { - _activeChar.addItem("LuxuryFortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_IN_THE_LUXURY_FORTUNE_READING); - } - else - { - _activeChar.addItem("FortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); - } - sm.addPcName(_activeChar); - sm.addLong(reward.getCount()); - sm.addItemName(new L2ItemInstance(reward.getId())); - _activeChar.broadcastPacket(sm, 1000); + packet.writeD(reward.getKey().getClientId()); + packet.writeD(item.getId()); + packet.writeD((int) item.getCount()); } } - else - { - packet.writeD(0x00); - } return true; } } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java index 4d58f5d294..233363fde2 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java @@ -17,32 +17,30 @@ package com.l2jmobius.gameserver.network.serverpackets.luckygame; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.network.OutgoingPackets; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; /** - * @author Mobius + * @author Sdw */ public class ExStartLuckyGame implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _type = 0; - private int _count = 0; + private final LuckyGameType _type; + private final int _ticketCount; - public ExStartLuckyGame(L2PcInstance activeChar, int type) + public ExStartLuckyGame(LuckyGameType type, long ticketCount) { _type = type; - _count = (int) activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1); + _ticketCount = (int) ticketCount; } @Override public boolean write(PacketWriter packet) { OutgoingPackets.EX_START_LUCKY_GAME.writeId(packet); - packet.writeD(_type); - packet.writeD(_count); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); return true; } } diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/LuckyGameData.xml b/L2J_Mobius_3.0_Helios/dist/game/data/LuckyGameData.xml index c65bb0fff5..595b4d47f0 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/LuckyGameData.xml +++ b/L2J_Mobius_3.0_Helios/dist/game/data/LuckyGameData.xml @@ -1,225 +1,224 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java index 9b806fdb97..d121a6c06f 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java @@ -17,6 +17,7 @@ package events.EveTheFortuneTeller; import com.l2jmobius.gameserver.enums.ChatType; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.model.Location; import com.l2jmobius.gameserver.model.actor.L2Npc; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; @@ -36,6 +37,9 @@ public final class EveTheFortuneTeller extends LongTimeEvent // NPCs private static final int EVE = 8542; private static final int JAYCE = 8540; + // Items + private static final int FORTUNE_READING_TICKET = 23767; + private static final int LUXURY_FORTUNE_READING_TICKET = 23768; // Misc private static final Location JAYCE_SPAWN = new Location(148090, 26644, -2209, 16383); private static final NpcStringId[] JAYCE_TEXT = @@ -71,12 +75,12 @@ public final class EveTheFortuneTeller extends LongTimeEvent } case "FortuneReadingGame": { - player.sendPacket(new ExStartLuckyGame(player, 1)); + player.sendPacket(new ExStartLuckyGame(LuckyGameType.NORMAL, player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1))); break; } case "LuxuryFortuneReadingGame": { - player.sendPacket(new ExStartLuckyGame(player, 2)); + player.sendPacket(new ExStartLuckyGame(LuckyGameType.LUXURY, player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1))); break; } case "JAYCE_SHOUT": diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/xsd/LuckyGameData.xsd b/L2J_Mobius_3.0_Helios/dist/game/data/xsd/LuckyGameData.xsd index 95f23b1e7f..17e958d81f 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/xsd/LuckyGameData.xsd +++ b/L2J_Mobius_3.0_Helios/dist/game/data/xsd/LuckyGameData.xsd @@ -2,56 +2,68 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java index 02d7243e5c..d732ccb769 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java @@ -17,25 +17,26 @@ package com.l2jmobius.gameserver.data.xml.impl; import java.io.File; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; import com.l2jmobius.commons.util.IGameXmlReader; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemPointHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; /** - * @author Mathael + * @author Sdw */ public class LuckyGameData implements IGameXmlReader { - private static final List _fortuneReadingTicketRewards = new ArrayList<>(); - private static final List _luxuryFortuneReadingTicketRewards = new ArrayList<>(); - private static final List _rareLuxuryFortuneReadingTicketRewards = new ArrayList<>(); + private final Map _luckyGame = new HashMap<>(); + + final AtomicInteger _serverPlay = new AtomicInteger(); protected LuckyGameData() { @@ -45,112 +46,62 @@ public class LuckyGameData implements IGameXmlReader @Override public void load() { - _fortuneReadingTicketRewards.clear(); - _luxuryFortuneReadingTicketRewards.clear(); - _rareLuxuryFortuneReadingTicketRewards.clear(); - + _luckyGame.clear(); parseDatapackFile("data/LuckyGameData.xml"); - - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fortuneReadingTicketRewards.size() + " Normal item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luxuryFortuneReadingTicketRewards.size() + " Luxury item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rareLuxuryFortuneReadingTicketRewards.size() + " Rare item rewards."); + LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luckyGame.size() + " lucky game data."); } @Override public void parseDocument(Document doc, File f) { - for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) + forEach(doc, "list", listNode -> forEach(listNode, "luckygame", rewardNode -> { - if ("list".equalsIgnoreCase(n.getNodeName())) + final LuckyGameDataHolder holder = new LuckyGameDataHolder(new StatsSet(parseAttributes(rewardNode))); + + forEach(rewardNode, "common_reward", commonRewardNode -> forEach(commonRewardNode, "item", itemNode -> { - final NamedNodeMap at = n.getAttributes(); - final Node attribute = at.getNamedItem("enabled"); - if ((attribute != null) && Boolean.parseBoolean(attribute.getNodeValue())) // forEach(uniqueRewardNode, "item", itemNode -> + { + holder.addUniqueReward(new ItemPointHolder(new StatsSet(parseAttributes(itemNode)))); + })); + + forEach(rewardNode, "modify_reward", uniqueRewardNode -> + { + holder.setMinModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "min_game")); + holder.setMaxModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "max_game")); + forEach(uniqueRewardNode, "item", itemNode -> { - for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) - { - if ("fortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _fortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("luxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _luxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("rareLuxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _rareLuxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - } - } - } - } + final StatsSet stats = new StatsSet(parseAttributes(itemNode)); + holder.addModifyReward(new ItemChanceHolder(stats.getInt("id"), stats.getDouble("chance"), stats.getLong("count"))); + }); + }); + + _luckyGame.put(parseInteger(rewardNode.getAttributes(), "index"), holder); + })); } - public static ItemHolder getRandomNormalReward() + public int getLuckyGameCount() { - return _fortuneReadingTicketRewards.get(Rnd.get(_fortuneReadingTicketRewards.size())); + return _luckyGame.size(); } - public static ItemHolder getRandomLuxuryReward() + public LuckyGameDataHolder getLuckyGameDataByIndex(int index) { - return _luxuryFortuneReadingTicketRewards.get(Rnd.get(_luxuryFortuneReadingTicketRewards.size())); + return _luckyGame.get(index); } - public static ItemHolder getRandomRareReward() + public int increaseGame() { - return _rareLuxuryFortuneReadingTicketRewards.get(Rnd.get(_rareLuxuryFortuneReadingTicketRewards.size())); + return _serverPlay.incrementAndGet(); + } + + public int getServerPlay() + { + return _serverPlay.get(); } public static LuckyGameData getInstance() diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java new file mode 100644 index 0000000000..af1d82c1e1 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameItemType +{ + COMMON(1), + UNIQUE(2), + RARE(3); + + private final int _clientId; + + LuckyGameItemType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java new file mode 100644 index 0000000000..5a974d05d0 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameResultType +{ + INVALID_CAPACITY(-2), + INVALID_ITEM_COUNT(-1), + DISABLED(0), + SUCCESS(1); + + private final int _clientId; + + private LuckyGameResultType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/enums/LuckyGameType.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/enums/LuckyGameType.java new file mode 100644 index 0000000000..f8f7938727 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/enums/LuckyGameType.java @@ -0,0 +1,27 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameType +{ + NONE, + NORMAL, + LUXURY +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java new file mode 100644 index 0000000000..5d2fbfb7b8 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java @@ -0,0 +1,53 @@ +/* + * 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 com.l2jmobius.gameserver.model.holders; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class ItemPointHolder extends ItemHolder +{ + private final int _points; + + public ItemPointHolder(StatsSet params) + { + this(params.getInt("id"), params.getLong("count"), params.getInt("points")); + } + + public ItemPointHolder(int id, long count, int points) + { + super(id, count); + _points = points; + } + + /** + * Gets the point. + * @return the number of point to get the item + */ + public int getPoints() + { + return _points; + } + + @Override + public String toString() + { + return "[" + getClass().getSimpleName() + "] ID: " + getId() + ", count: " + getCount() + ", points: " + _points; + } +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java new file mode 100644 index 0000000000..43e93e30c5 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java @@ -0,0 +1,102 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.model.holders; + +import java.util.ArrayList; +import java.util.List; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class LuckyGameDataHolder +{ + final private int _index; + final private int _turningPoints; + final private List _commonRewards = new ArrayList<>(); + final private List _uniqueRewards = new ArrayList<>(); + final private List _modifyRewards = new ArrayList<>(); + private int _minModifyRewardGame; + private int _maxModifyRewardGame; + + public LuckyGameDataHolder(StatsSet params) + { + _index = params.getInt("index"); + _turningPoints = params.getInt("turning_point"); + } + + public void addCommonReward(ItemChanceHolder item) + { + _commonRewards.add(item); + } + + public void addUniqueReward(ItemPointHolder item) + { + _uniqueRewards.add(item); + } + + public void addModifyReward(ItemChanceHolder item) + { + _modifyRewards.add(item); + } + + public List getCommonReward() + { + return _commonRewards; + } + + public List getUniqueReward() + { + return _uniqueRewards; + } + + public List getModifyReward() + { + return _modifyRewards; + } + + public void setMinModifyRewardGame(int minModifyRewardGame) + { + _minModifyRewardGame = minModifyRewardGame; + } + + public void setMaxModifyRewardGame(int maxModifyRewardGame) + { + _maxModifyRewardGame = maxModifyRewardGame; + } + + public int getMinModifyRewardGame() + { + return _minModifyRewardGame; + } + + public int getMaxModifyRewardGame() + { + return _maxModifyRewardGame; + } + + public int getIndex() + { + return _index; + } + + public int getTurningPoints() + { + return _turningPoints; + } +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java index 7698c1f912..fd1fb41f5f 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java @@ -57,6 +57,8 @@ public class PlayerVariables extends AbstractVariables public static final String REVELATION_SKILL_1_DUAL_CLASS = "DualclassRevelationSkill1"; public static final String REVELATION_SKILL_2_DUAL_CLASS = "DualclassRevelationSkill2"; public static final String EXTEND_DROP = "EXTEND_DROP"; + public static final String FORTUNE_TELLING_VARIABLE = "FortuneTelling"; + public static final String FORTUNE_TELLING_BLACK_CAT_VARIABLE = "FortuneTellingBlackCat"; private final int _objectId; diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index d52932e6d9..669eadd34c 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -69,6 +69,8 @@ import com.l2jmobius.gameserver.network.clientpackets.dailymission.RequestTodoLi import com.l2jmobius.gameserver.network.clientpackets.ensoul.RequestItemEnsoul; import com.l2jmobius.gameserver.network.clientpackets.faction.RequestUserFactionInfo; import com.l2jmobius.gameserver.network.clientpackets.friend.RequestFriendDetailInfo; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGamePlay; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGameStartInfo; import com.l2jmobius.gameserver.network.clientpackets.mentoring.ConfirmMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeWaitingList; @@ -329,8 +331,8 @@ public enum ExIncomingPackets implements IIncomingPackets REQUEST_ABILITY_WND_OPEN(0xEE, RequestAbilityWndOpen::new, ConnectionState.IN_GAME), REQUEST_ABILITY_WND_CLOSE(0xEF, RequestAbilityWndClose::new, ConnectionState.IN_GAME), EX_PC_CAFE_REQUEST_OPEN_WINDOW_WITHOUT_NPC(0xF0, ExPCCafeRequestOpenWindowWithoutNPC::new, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_START_INFO(0xF1, null, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_PLAY(0xF2, null, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_START_INFO(0xF1, RequestLuckyGameStartInfo::new, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_PLAY(0xF2, RequestLuckyGamePlay::new, ConnectionState.IN_GAME), NOTIFY_TRAINING_ROOM_END(0xF3, null, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_PUSH_ONE(0xF4, RequestNewEnchantPushOne::new, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_REMOVE_ONE(0xF5, RequestNewEnchantRemoveOne::new, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java index 72f40dcba6..1e48d2cfb6 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java @@ -16,30 +16,169 @@ */ package com.l2jmobius.gameserver.network.clientpackets.luckygame; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map.Entry; + import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.commons.util.CommonUtil; +import com.l2jmobius.commons.util.Rnd; +import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; +import com.l2jmobius.gameserver.datatables.ItemTable; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; +import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; +import com.l2jmobius.gameserver.model.variables.PlayerVariables; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; +import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; import com.l2jmobius.gameserver.network.serverpackets.luckygame.ExBettingLuckyGameResult; /** - * @author Mobius + * @author Sdw */ public class RequestLuckyGamePlay implements IClientIncomingPacket { - private int _type; - private int _count; + private static final int FORTUNE_READING_TICKET = 23767; + private static final int LUXURY_FORTUNE_READING_TICKET = 23768; + private LuckyGameType _type; + private int _reading; @Override public boolean read(L2GameClient client, PacketReader packet) { - _type = packet.readD(); // luxury = 2, normal = 1 - _count = packet.readD(); // count + final int type = CommonUtil.constrain(packet.readD(), 0, LuckyGameType.values().length); + _type = LuckyGameType.values()[type]; + _reading = CommonUtil.constrain(packet.readD(), 0, 50); // max play is 50 return true; } @Override public void run(L2GameClient client) { - client.getActiveChar().sendPacket(new ExBettingLuckyGameResult(client.getActiveChar(), _type, _count)); + final L2PcInstance player = client.getActiveChar(); + if (player == null) + { + return; + } + + final int index = _type == LuckyGameType.LUXURY ? 102 : 2; // move to event config + + final LuckyGameDataHolder holder = LuckyGameData.getInstance().getLuckyGameDataByIndex(index); + if (holder == null) + { + return; + } + + final long tickets = _type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1); + if (tickets < _reading) + { + player.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + int playCount = player.getVariables().getInt(PlayerVariables.FORTUNE_TELLING_VARIABLE, 0); + boolean blackCat = player.getVariables().getBoolean(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, false); + final EnumMap> rewards = new EnumMap<>(LuckyGameItemType.class); + for (int i = 0; i < _reading; i++) + { + final double chance = 100 * Rnd.nextDouble(); + double totalChance = 0; + + for (ItemChanceHolder item : holder.getCommonReward()) + { + totalChance += item.getChance(); + if (totalChance >= chance) + { + rewards.computeIfAbsent(LuckyGameItemType.COMMON, k -> new ArrayList<>()).add(item); + break; + } + } + playCount++; + if ((playCount >= holder.getMinModifyRewardGame()) && (playCount <= holder.getMaxModifyRewardGame()) && !blackCat) + { + final List modifyReward = holder.getModifyReward(); + final double chanceModify = 100 * Rnd.nextDouble(); + totalChance = 0; + + for (ItemChanceHolder item : modifyReward) + { + totalChance += item.getChance(); + if (totalChance >= chanceModify) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(item); + blackCat = true; + break; + } + } + + if (playCount == holder.getMaxModifyRewardGame()) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(modifyReward.get(Rnd.get(modifyReward.size()))); + blackCat = true; + } + } + } + + final int totalWeight = rewards.values().stream().mapToInt(list -> list.stream().mapToInt(item -> ItemTable.getInstance().getTemplate(item.getId()).getWeight()).sum()).sum(); + + // Check inventory capacity + if ((rewards.size() > 0) && (!player.getInventory().validateCapacity(rewards.size()) || !player.getInventory().validateWeight(totalWeight))) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_CAPACITY : ExBettingLuckyGameResult.NORMAL_INVALID_CAPACITY); + player.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); + return; + } + + if (!player.destroyItemByItemId("LuckyGame", _type == LuckyGameType.LUXURY ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _reading, player, true)) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + for (int i = 0; i < _reading; i++) + { + final int serverGameNumber = LuckyGameData.getInstance().increaseGame(); + holder.getUniqueReward().stream().filter(reward -> reward.getPoints() == serverGameNumber).forEach(item -> rewards.computeIfAbsent(LuckyGameItemType.UNIQUE, k -> new ArrayList<>()).add(item)); + } + + player.sendPacket(new ExBettingLuckyGameResult(LuckyGameResultType.SUCCESS, _type, rewards, (int) (_type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1)))); + + final InventoryUpdate iu = new InventoryUpdate(); + for (Entry> reward : rewards.entrySet()) + { + for (ItemHolder r : reward.getValue()) + { + final L2ItemInstance item = player.addItem("LuckyGame", r.getId(), r.getCount(), player, true); + iu.addItem(item); + if (reward.getKey() == LuckyGameItemType.UNIQUE) + { + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); + sm.addPcName(player); + sm.addLong(r.getCount()); + sm.addItemName(item); + player.broadcastPacket(sm, 1000); + break; + } + + } + } + + player.sendInventoryUpdate(iu); + + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_VARIABLE, playCount >= 50 ? (playCount - 50) : playCount); + if (blackCat && (playCount < 50)) + { + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, true); + } } } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java new file mode 100644 index 0000000000..e39f110a76 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.network.clientpackets.luckygame; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; + +/** + * @author Sdw + */ +public class RequestLuckyGameStartInfo implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return true; + } + + @Override + public void run(L2GameClient client) + { + + } +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java index 32d7ebc372..d36f6bb0c3 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java @@ -16,121 +16,69 @@ */ package com.l2jmobius.gameserver.network.serverpackets.luckygame; -import java.util.ArrayList; +import java.util.EnumMap; import java.util.List; +import java.util.Map.Entry; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.model.holders.ItemHolder; -import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.network.OutgoingPackets; -import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; -import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** - * @author Mobius + * @author Sdw */ public class ExBettingLuckyGameResult implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _count = 0; - private int _type = 0; - private final L2PcInstance _activeChar; + public static final ExBettingLuckyGameResult NORMAL_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.LUXURY); + public static final ExBettingLuckyGameResult NORMAL_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.LUXURY); - public ExBettingLuckyGameResult(L2PcInstance activeChar, int type, int count) + private final LuckyGameResultType _result; + private final LuckyGameType _type; + private final EnumMap> _rewards; + private final int _ticketCount; + private final int _size; + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type) { - _count = count; + _result = result; _type = type; - _activeChar = activeChar; + _rewards = new EnumMap<>(LuckyGameItemType.class); + _ticketCount = 0; + _size = 0; + } + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type, EnumMap> rewards, int ticketCount) + { + _result = result; + _type = type; + _rewards = rewards; + _ticketCount = ticketCount; + _size = (int) rewards.values().stream().mapToLong(i -> i.stream().count()).sum(); } @Override public boolean write(PacketWriter packet) { - // Calculate rewards - final List rewards = new ArrayList<>(); - int totalWeight = 0; - for (int rewardCounter = 0; rewardCounter < _count; rewardCounter++) - { - if (Rnd.get(3) == 0) // 1 out of 3 chance - { - ItemHolder reward = null; - if (_type == 2) - { - if (_count >= 40) - { - reward = LuckyGameData.getRandomRareReward(); - } - else - { - reward = LuckyGameData.getRandomLuxuryReward(); - } - } - else - { - reward = LuckyGameData.getRandomNormalReward(); - } - rewards.add(reward); - totalWeight += new L2ItemInstance(reward.getId()).getItem().getWeight() * reward.getCount(); - } - } - - // Check inventory capacity - if ((rewards.size() > 0) && (!_activeChar.getInventory().validateCapacity(rewards.size()) || !_activeChar.getInventory().validateWeight(totalWeight))) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); - return false; - } - - if (_activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1) < _count) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); - return false; - } - - // Remove tickets - _activeChar.getInventory().destroyItemByItemId("FortuneTelling", _type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _count, _activeChar, "FortuneTelling"); - OutgoingPackets.EX_BETTING_LUCKY_GAME_RESULT.writeId(packet); - packet.writeD(0x01); // 0 disabled, 1 enabled - packet.writeD(0x01); // ? - packet.writeD((int) _activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1)); // Count remaining tickets - - if (rewards.size() > 0) + packet.writeD(_result.getClientId()); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); + packet.writeD(_size); + for (Entry> reward : _rewards.entrySet()) { - packet.writeD(rewards.size()); - for (ItemHolder reward : rewards) + for (ItemHolder item : reward.getValue()) { - packet.writeD(0x02); // normal = 1, rare = 2 (forcing 2) - packet.writeD(reward.getId()); - packet.writeD((int) reward.getCount()); - final SystemMessage sm; - if (_type == 2) - { - _activeChar.addItem("LuxuryFortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_IN_THE_LUXURY_FORTUNE_READING); - } - else - { - _activeChar.addItem("FortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); - } - sm.addPcName(_activeChar); - sm.addLong(reward.getCount()); - sm.addItemName(new L2ItemInstance(reward.getId())); - _activeChar.broadcastPacket(sm, 1000); + packet.writeD(reward.getKey().getClientId()); + packet.writeD(item.getId()); + packet.writeD((int) item.getCount()); } } - else - { - packet.writeD(0x00); - } return true; } } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java index 4d58f5d294..233363fde2 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java @@ -17,32 +17,30 @@ package com.l2jmobius.gameserver.network.serverpackets.luckygame; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.network.OutgoingPackets; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; /** - * @author Mobius + * @author Sdw */ public class ExStartLuckyGame implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _type = 0; - private int _count = 0; + private final LuckyGameType _type; + private final int _ticketCount; - public ExStartLuckyGame(L2PcInstance activeChar, int type) + public ExStartLuckyGame(LuckyGameType type, long ticketCount) { _type = type; - _count = (int) activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1); + _ticketCount = (int) ticketCount; } @Override public boolean write(PacketWriter packet) { OutgoingPackets.EX_START_LUCKY_GAME.writeId(packet); - packet.writeD(_type); - packet.writeD(_count); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); return true; } } diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/LuckyGameData.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/LuckyGameData.xml index c65bb0fff5..595b4d47f0 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/LuckyGameData.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/LuckyGameData.xml @@ -1,225 +1,224 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java index 9b806fdb97..d121a6c06f 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/events/EveTheFortuneTeller/EveTheFortuneTeller.java @@ -17,6 +17,7 @@ package events.EveTheFortuneTeller; import com.l2jmobius.gameserver.enums.ChatType; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.model.Location; import com.l2jmobius.gameserver.model.actor.L2Npc; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; @@ -36,6 +37,9 @@ public final class EveTheFortuneTeller extends LongTimeEvent // NPCs private static final int EVE = 8542; private static final int JAYCE = 8540; + // Items + private static final int FORTUNE_READING_TICKET = 23767; + private static final int LUXURY_FORTUNE_READING_TICKET = 23768; // Misc private static final Location JAYCE_SPAWN = new Location(148090, 26644, -2209, 16383); private static final NpcStringId[] JAYCE_TEXT = @@ -71,12 +75,12 @@ public final class EveTheFortuneTeller extends LongTimeEvent } case "FortuneReadingGame": { - player.sendPacket(new ExStartLuckyGame(player, 1)); + player.sendPacket(new ExStartLuckyGame(LuckyGameType.NORMAL, player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1))); break; } case "LuxuryFortuneReadingGame": { - player.sendPacket(new ExStartLuckyGame(player, 2)); + player.sendPacket(new ExStartLuckyGame(LuckyGameType.LUXURY, player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1))); break; } case "JAYCE_SHOUT": diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/LuckyGameData.xsd b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/LuckyGameData.xsd index 95f23b1e7f..405a26e9e9 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/LuckyGameData.xsd +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/LuckyGameData.xsd @@ -1,57 +1,69 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java index 02d7243e5c..d732ccb769 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java @@ -17,25 +17,26 @@ package com.l2jmobius.gameserver.data.xml.impl; import java.io.File; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; import com.l2jmobius.commons.util.IGameXmlReader; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemPointHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; /** - * @author Mathael + * @author Sdw */ public class LuckyGameData implements IGameXmlReader { - private static final List _fortuneReadingTicketRewards = new ArrayList<>(); - private static final List _luxuryFortuneReadingTicketRewards = new ArrayList<>(); - private static final List _rareLuxuryFortuneReadingTicketRewards = new ArrayList<>(); + private final Map _luckyGame = new HashMap<>(); + + final AtomicInteger _serverPlay = new AtomicInteger(); protected LuckyGameData() { @@ -45,112 +46,62 @@ public class LuckyGameData implements IGameXmlReader @Override public void load() { - _fortuneReadingTicketRewards.clear(); - _luxuryFortuneReadingTicketRewards.clear(); - _rareLuxuryFortuneReadingTicketRewards.clear(); - + _luckyGame.clear(); parseDatapackFile("data/LuckyGameData.xml"); - - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fortuneReadingTicketRewards.size() + " Normal item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luxuryFortuneReadingTicketRewards.size() + " Luxury item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rareLuxuryFortuneReadingTicketRewards.size() + " Rare item rewards."); + LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luckyGame.size() + " lucky game data."); } @Override public void parseDocument(Document doc, File f) { - for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) + forEach(doc, "list", listNode -> forEach(listNode, "luckygame", rewardNode -> { - if ("list".equalsIgnoreCase(n.getNodeName())) + final LuckyGameDataHolder holder = new LuckyGameDataHolder(new StatsSet(parseAttributes(rewardNode))); + + forEach(rewardNode, "common_reward", commonRewardNode -> forEach(commonRewardNode, "item", itemNode -> { - final NamedNodeMap at = n.getAttributes(); - final Node attribute = at.getNamedItem("enabled"); - if ((attribute != null) && Boolean.parseBoolean(attribute.getNodeValue())) // forEach(uniqueRewardNode, "item", itemNode -> + { + holder.addUniqueReward(new ItemPointHolder(new StatsSet(parseAttributes(itemNode)))); + })); + + forEach(rewardNode, "modify_reward", uniqueRewardNode -> + { + holder.setMinModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "min_game")); + holder.setMaxModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "max_game")); + forEach(uniqueRewardNode, "item", itemNode -> { - for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) - { - if ("fortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _fortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("luxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _luxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("rareLuxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _rareLuxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - } - } - } - } + final StatsSet stats = new StatsSet(parseAttributes(itemNode)); + holder.addModifyReward(new ItemChanceHolder(stats.getInt("id"), stats.getDouble("chance"), stats.getLong("count"))); + }); + }); + + _luckyGame.put(parseInteger(rewardNode.getAttributes(), "index"), holder); + })); } - public static ItemHolder getRandomNormalReward() + public int getLuckyGameCount() { - return _fortuneReadingTicketRewards.get(Rnd.get(_fortuneReadingTicketRewards.size())); + return _luckyGame.size(); } - public static ItemHolder getRandomLuxuryReward() + public LuckyGameDataHolder getLuckyGameDataByIndex(int index) { - return _luxuryFortuneReadingTicketRewards.get(Rnd.get(_luxuryFortuneReadingTicketRewards.size())); + return _luckyGame.get(index); } - public static ItemHolder getRandomRareReward() + public int increaseGame() { - return _rareLuxuryFortuneReadingTicketRewards.get(Rnd.get(_rareLuxuryFortuneReadingTicketRewards.size())); + return _serverPlay.incrementAndGet(); + } + + public int getServerPlay() + { + return _serverPlay.get(); } public static LuckyGameData getInstance() diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java new file mode 100644 index 0000000000..4d252020a1 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameItemType +{ + COMMON(1), + UNIQUE(2), + RARE(3); + + private final int _clientId; + + LuckyGameItemType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java new file mode 100644 index 0000000000..bd224076c1 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameResultType +{ + INVALID_CAPACITY(-2), + INVALID_ITEM_COUNT(-1), + DISABLED(0), + SUCCESS(1); + + private final int _clientId; + + private LuckyGameResultType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/enums/LuckyGameType.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/enums/LuckyGameType.java new file mode 100644 index 0000000000..01c66eeb6f --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/enums/LuckyGameType.java @@ -0,0 +1,27 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameType +{ + NONE, + NORMAL, + LUXURY +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java new file mode 100644 index 0000000000..3aba6c78d4 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java @@ -0,0 +1,53 @@ +/* + * 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 com.l2jmobius.gameserver.model.holders; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class ItemPointHolder extends ItemHolder +{ + private final int _points; + + public ItemPointHolder(StatsSet params) + { + this(params.getInt("id"), params.getLong("count"), params.getInt("points")); + } + + public ItemPointHolder(int id, long count, int points) + { + super(id, count); + _points = points; + } + + /** + * Gets the point. + * @return the number of point to get the item + */ + public int getPoints() + { + return _points; + } + + @Override + public String toString() + { + return "[" + getClass().getSimpleName() + "] ID: " + getId() + ", count: " + getCount() + ", points: " + _points; + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java new file mode 100644 index 0000000000..87cd0b1cb5 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java @@ -0,0 +1,102 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.model.holders; + +import java.util.ArrayList; +import java.util.List; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class LuckyGameDataHolder +{ + final private int _index; + final private int _turningPoints; + final private List _commonRewards = new ArrayList<>(); + final private List _uniqueRewards = new ArrayList<>(); + final private List _modifyRewards = new ArrayList<>(); + private int _minModifyRewardGame; + private int _maxModifyRewardGame; + + public LuckyGameDataHolder(StatsSet params) + { + _index = params.getInt("index"); + _turningPoints = params.getInt("turning_point"); + } + + public void addCommonReward(ItemChanceHolder item) + { + _commonRewards.add(item); + } + + public void addUniqueReward(ItemPointHolder item) + { + _uniqueRewards.add(item); + } + + public void addModifyReward(ItemChanceHolder item) + { + _modifyRewards.add(item); + } + + public List getCommonReward() + { + return _commonRewards; + } + + public List getUniqueReward() + { + return _uniqueRewards; + } + + public List getModifyReward() + { + return _modifyRewards; + } + + public void setMinModifyRewardGame(int minModifyRewardGame) + { + _minModifyRewardGame = minModifyRewardGame; + } + + public void setMaxModifyRewardGame(int maxModifyRewardGame) + { + _maxModifyRewardGame = maxModifyRewardGame; + } + + public int getMinModifyRewardGame() + { + return _minModifyRewardGame; + } + + public int getMaxModifyRewardGame() + { + return _maxModifyRewardGame; + } + + public int getIndex() + { + return _index; + } + + public int getTurningPoints() + { + return _turningPoints; + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java index 7698c1f912..fd1fb41f5f 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java @@ -57,6 +57,8 @@ public class PlayerVariables extends AbstractVariables public static final String REVELATION_SKILL_1_DUAL_CLASS = "DualclassRevelationSkill1"; public static final String REVELATION_SKILL_2_DUAL_CLASS = "DualclassRevelationSkill2"; public static final String EXTEND_DROP = "EXTEND_DROP"; + public static final String FORTUNE_TELLING_VARIABLE = "FortuneTelling"; + public static final String FORTUNE_TELLING_BLACK_CAT_VARIABLE = "FortuneTellingBlackCat"; private final int _objectId; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index 6e8925deac..3c7a97a44a 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -69,6 +69,8 @@ import com.l2jmobius.gameserver.network.clientpackets.dailymission.RequestTodoLi import com.l2jmobius.gameserver.network.clientpackets.ensoul.RequestItemEnsoul; import com.l2jmobius.gameserver.network.clientpackets.faction.RequestUserFactionInfo; import com.l2jmobius.gameserver.network.clientpackets.friend.RequestFriendDetailInfo; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGamePlay; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGameStartInfo; import com.l2jmobius.gameserver.network.clientpackets.mentoring.ConfirmMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeWaitingList; @@ -334,8 +336,8 @@ public enum ExIncomingPackets implements IIncomingPackets REQUEST_ABILITY_WND_OPEN(0xEE, RequestAbilityWndOpen::new, ConnectionState.IN_GAME), REQUEST_ABILITY_WND_CLOSE(0xEF, RequestAbilityWndClose::new, ConnectionState.IN_GAME), EX_PC_CAFE_REQUEST_OPEN_WINDOW_WITHOUT_NPC(0xF0, ExPCCafeRequestOpenWindowWithoutNPC::new, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_START_INFO(0xF1, null, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_PLAY(0xF2, null, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_START_INFO(0xF1, RequestLuckyGameStartInfo::new, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_PLAY(0xF2, RequestLuckyGamePlay::new, ConnectionState.IN_GAME), NOTIFY_TRAINING_ROOM_END(0xF3, null, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_PUSH_ONE(0xF4, RequestNewEnchantPushOne::new, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_REMOVE_ONE(0xF5, RequestNewEnchantRemoveOne::new, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java index 72f40dcba6..1e48d2cfb6 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java @@ -16,30 +16,169 @@ */ package com.l2jmobius.gameserver.network.clientpackets.luckygame; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map.Entry; + import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.commons.util.CommonUtil; +import com.l2jmobius.commons.util.Rnd; +import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; +import com.l2jmobius.gameserver.datatables.ItemTable; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; +import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; +import com.l2jmobius.gameserver.model.variables.PlayerVariables; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; +import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; import com.l2jmobius.gameserver.network.serverpackets.luckygame.ExBettingLuckyGameResult; /** - * @author Mobius + * @author Sdw */ public class RequestLuckyGamePlay implements IClientIncomingPacket { - private int _type; - private int _count; + private static final int FORTUNE_READING_TICKET = 23767; + private static final int LUXURY_FORTUNE_READING_TICKET = 23768; + private LuckyGameType _type; + private int _reading; @Override public boolean read(L2GameClient client, PacketReader packet) { - _type = packet.readD(); // luxury = 2, normal = 1 - _count = packet.readD(); // count + final int type = CommonUtil.constrain(packet.readD(), 0, LuckyGameType.values().length); + _type = LuckyGameType.values()[type]; + _reading = CommonUtil.constrain(packet.readD(), 0, 50); // max play is 50 return true; } @Override public void run(L2GameClient client) { - client.getActiveChar().sendPacket(new ExBettingLuckyGameResult(client.getActiveChar(), _type, _count)); + final L2PcInstance player = client.getActiveChar(); + if (player == null) + { + return; + } + + final int index = _type == LuckyGameType.LUXURY ? 102 : 2; // move to event config + + final LuckyGameDataHolder holder = LuckyGameData.getInstance().getLuckyGameDataByIndex(index); + if (holder == null) + { + return; + } + + final long tickets = _type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1); + if (tickets < _reading) + { + player.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + int playCount = player.getVariables().getInt(PlayerVariables.FORTUNE_TELLING_VARIABLE, 0); + boolean blackCat = player.getVariables().getBoolean(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, false); + final EnumMap> rewards = new EnumMap<>(LuckyGameItemType.class); + for (int i = 0; i < _reading; i++) + { + final double chance = 100 * Rnd.nextDouble(); + double totalChance = 0; + + for (ItemChanceHolder item : holder.getCommonReward()) + { + totalChance += item.getChance(); + if (totalChance >= chance) + { + rewards.computeIfAbsent(LuckyGameItemType.COMMON, k -> new ArrayList<>()).add(item); + break; + } + } + playCount++; + if ((playCount >= holder.getMinModifyRewardGame()) && (playCount <= holder.getMaxModifyRewardGame()) && !blackCat) + { + final List modifyReward = holder.getModifyReward(); + final double chanceModify = 100 * Rnd.nextDouble(); + totalChance = 0; + + for (ItemChanceHolder item : modifyReward) + { + totalChance += item.getChance(); + if (totalChance >= chanceModify) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(item); + blackCat = true; + break; + } + } + + if (playCount == holder.getMaxModifyRewardGame()) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(modifyReward.get(Rnd.get(modifyReward.size()))); + blackCat = true; + } + } + } + + final int totalWeight = rewards.values().stream().mapToInt(list -> list.stream().mapToInt(item -> ItemTable.getInstance().getTemplate(item.getId()).getWeight()).sum()).sum(); + + // Check inventory capacity + if ((rewards.size() > 0) && (!player.getInventory().validateCapacity(rewards.size()) || !player.getInventory().validateWeight(totalWeight))) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_CAPACITY : ExBettingLuckyGameResult.NORMAL_INVALID_CAPACITY); + player.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); + return; + } + + if (!player.destroyItemByItemId("LuckyGame", _type == LuckyGameType.LUXURY ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _reading, player, true)) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + for (int i = 0; i < _reading; i++) + { + final int serverGameNumber = LuckyGameData.getInstance().increaseGame(); + holder.getUniqueReward().stream().filter(reward -> reward.getPoints() == serverGameNumber).forEach(item -> rewards.computeIfAbsent(LuckyGameItemType.UNIQUE, k -> new ArrayList<>()).add(item)); + } + + player.sendPacket(new ExBettingLuckyGameResult(LuckyGameResultType.SUCCESS, _type, rewards, (int) (_type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1)))); + + final InventoryUpdate iu = new InventoryUpdate(); + for (Entry> reward : rewards.entrySet()) + { + for (ItemHolder r : reward.getValue()) + { + final L2ItemInstance item = player.addItem("LuckyGame", r.getId(), r.getCount(), player, true); + iu.addItem(item); + if (reward.getKey() == LuckyGameItemType.UNIQUE) + { + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); + sm.addPcName(player); + sm.addLong(r.getCount()); + sm.addItemName(item); + player.broadcastPacket(sm, 1000); + break; + } + + } + } + + player.sendInventoryUpdate(iu); + + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_VARIABLE, playCount >= 50 ? (playCount - 50) : playCount); + if (blackCat && (playCount < 50)) + { + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, true); + } } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java new file mode 100644 index 0000000000..8c6ff83984 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.network.clientpackets.luckygame; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; + +/** + * @author Sdw + */ +public class RequestLuckyGameStartInfo implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return true; + } + + @Override + public void run(L2GameClient client) + { + + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java index 32d7ebc372..d36f6bb0c3 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java @@ -16,121 +16,69 @@ */ package com.l2jmobius.gameserver.network.serverpackets.luckygame; -import java.util.ArrayList; +import java.util.EnumMap; import java.util.List; +import java.util.Map.Entry; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.model.holders.ItemHolder; -import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.network.OutgoingPackets; -import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; -import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** - * @author Mobius + * @author Sdw */ public class ExBettingLuckyGameResult implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _count = 0; - private int _type = 0; - private final L2PcInstance _activeChar; + public static final ExBettingLuckyGameResult NORMAL_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.LUXURY); + public static final ExBettingLuckyGameResult NORMAL_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.LUXURY); - public ExBettingLuckyGameResult(L2PcInstance activeChar, int type, int count) + private final LuckyGameResultType _result; + private final LuckyGameType _type; + private final EnumMap> _rewards; + private final int _ticketCount; + private final int _size; + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type) { - _count = count; + _result = result; _type = type; - _activeChar = activeChar; + _rewards = new EnumMap<>(LuckyGameItemType.class); + _ticketCount = 0; + _size = 0; + } + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type, EnumMap> rewards, int ticketCount) + { + _result = result; + _type = type; + _rewards = rewards; + _ticketCount = ticketCount; + _size = (int) rewards.values().stream().mapToLong(i -> i.stream().count()).sum(); } @Override public boolean write(PacketWriter packet) { - // Calculate rewards - final List rewards = new ArrayList<>(); - int totalWeight = 0; - for (int rewardCounter = 0; rewardCounter < _count; rewardCounter++) - { - if (Rnd.get(3) == 0) // 1 out of 3 chance - { - ItemHolder reward = null; - if (_type == 2) - { - if (_count >= 40) - { - reward = LuckyGameData.getRandomRareReward(); - } - else - { - reward = LuckyGameData.getRandomLuxuryReward(); - } - } - else - { - reward = LuckyGameData.getRandomNormalReward(); - } - rewards.add(reward); - totalWeight += new L2ItemInstance(reward.getId()).getItem().getWeight() * reward.getCount(); - } - } - - // Check inventory capacity - if ((rewards.size() > 0) && (!_activeChar.getInventory().validateCapacity(rewards.size()) || !_activeChar.getInventory().validateWeight(totalWeight))) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); - return false; - } - - if (_activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1) < _count) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); - return false; - } - - // Remove tickets - _activeChar.getInventory().destroyItemByItemId("FortuneTelling", _type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _count, _activeChar, "FortuneTelling"); - OutgoingPackets.EX_BETTING_LUCKY_GAME_RESULT.writeId(packet); - packet.writeD(0x01); // 0 disabled, 1 enabled - packet.writeD(0x01); // ? - packet.writeD((int) _activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1)); // Count remaining tickets - - if (rewards.size() > 0) + packet.writeD(_result.getClientId()); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); + packet.writeD(_size); + for (Entry> reward : _rewards.entrySet()) { - packet.writeD(rewards.size()); - for (ItemHolder reward : rewards) + for (ItemHolder item : reward.getValue()) { - packet.writeD(0x02); // normal = 1, rare = 2 (forcing 2) - packet.writeD(reward.getId()); - packet.writeD((int) reward.getCount()); - final SystemMessage sm; - if (_type == 2) - { - _activeChar.addItem("LuxuryFortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_IN_THE_LUXURY_FORTUNE_READING); - } - else - { - _activeChar.addItem("FortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); - } - sm.addPcName(_activeChar); - sm.addLong(reward.getCount()); - sm.addItemName(new L2ItemInstance(reward.getId())); - _activeChar.broadcastPacket(sm, 1000); + packet.writeD(reward.getKey().getClientId()); + packet.writeD(item.getId()); + packet.writeD((int) item.getCount()); } } - else - { - packet.writeD(0x00); - } return true; } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java index 4d58f5d294..233363fde2 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java @@ -17,32 +17,30 @@ package com.l2jmobius.gameserver.network.serverpackets.luckygame; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.network.OutgoingPackets; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; /** - * @author Mobius + * @author Sdw */ public class ExStartLuckyGame implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _type = 0; - private int _count = 0; + private final LuckyGameType _type; + private final int _ticketCount; - public ExStartLuckyGame(L2PcInstance activeChar, int type) + public ExStartLuckyGame(LuckyGameType type, long ticketCount) { _type = type; - _count = (int) activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1); + _ticketCount = (int) ticketCount; } @Override public boolean write(PacketWriter packet) { OutgoingPackets.EX_START_LUCKY_GAME.writeId(packet); - packet.writeD(_type); - packet.writeD(_count); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); return true; } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/LuckyGameData.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/LuckyGameData.xml index c65bb0fff5..595b4d47f0 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/LuckyGameData.xml +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/LuckyGameData.xml @@ -1,225 +1,224 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/LuckyGameData.xsd b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/LuckyGameData.xsd index 95f23b1e7f..17e958d81f 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/LuckyGameData.xsd +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/xsd/LuckyGameData.xsd @@ -2,56 +2,68 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java index 02d7243e5c..d732ccb769 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/data/xml/impl/LuckyGameData.java @@ -17,25 +17,26 @@ package com.l2jmobius.gameserver.data.xml.impl; import java.io.File; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; import com.l2jmobius.commons.util.IGameXmlReader; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemPointHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; /** - * @author Mathael + * @author Sdw */ public class LuckyGameData implements IGameXmlReader { - private static final List _fortuneReadingTicketRewards = new ArrayList<>(); - private static final List _luxuryFortuneReadingTicketRewards = new ArrayList<>(); - private static final List _rareLuxuryFortuneReadingTicketRewards = new ArrayList<>(); + private final Map _luckyGame = new HashMap<>(); + + final AtomicInteger _serverPlay = new AtomicInteger(); protected LuckyGameData() { @@ -45,112 +46,62 @@ public class LuckyGameData implements IGameXmlReader @Override public void load() { - _fortuneReadingTicketRewards.clear(); - _luxuryFortuneReadingTicketRewards.clear(); - _rareLuxuryFortuneReadingTicketRewards.clear(); - + _luckyGame.clear(); parseDatapackFile("data/LuckyGameData.xml"); - - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fortuneReadingTicketRewards.size() + " Normal item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luxuryFortuneReadingTicketRewards.size() + " Luxury item rewards."); - LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rareLuxuryFortuneReadingTicketRewards.size() + " Rare item rewards."); + LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luckyGame.size() + " lucky game data."); } @Override public void parseDocument(Document doc, File f) { - for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) + forEach(doc, "list", listNode -> forEach(listNode, "luckygame", rewardNode -> { - if ("list".equalsIgnoreCase(n.getNodeName())) + final LuckyGameDataHolder holder = new LuckyGameDataHolder(new StatsSet(parseAttributes(rewardNode))); + + forEach(rewardNode, "common_reward", commonRewardNode -> forEach(commonRewardNode, "item", itemNode -> { - final NamedNodeMap at = n.getAttributes(); - final Node attribute = at.getNamedItem("enabled"); - if ((attribute != null) && Boolean.parseBoolean(attribute.getNodeValue())) // forEach(uniqueRewardNode, "item", itemNode -> + { + holder.addUniqueReward(new ItemPointHolder(new StatsSet(parseAttributes(itemNode)))); + })); + + forEach(rewardNode, "modify_reward", uniqueRewardNode -> + { + holder.setMinModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "min_game")); + holder.setMaxModifyRewardGame(parseInteger(uniqueRewardNode.getAttributes(), "max_game")); + forEach(uniqueRewardNode, "item", itemNode -> { - for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) - { - if ("fortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _fortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("luxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _luxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - else if ("rareLuxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName())) - { - for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling()) - { - if ("item".equalsIgnoreCase(b.getNodeName())) - { - final NamedNodeMap attrs = b.getAttributes(); - - final int itemId = parseInteger(attrs, "id"); - final int count = parseInteger(attrs, "count"); - - if ((itemId == 0) || (count == 0)) - { - LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero."); - return; - } - - _rareLuxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count)); - } - } - } - } - } - } - } + final StatsSet stats = new StatsSet(parseAttributes(itemNode)); + holder.addModifyReward(new ItemChanceHolder(stats.getInt("id"), stats.getDouble("chance"), stats.getLong("count"))); + }); + }); + + _luckyGame.put(parseInteger(rewardNode.getAttributes(), "index"), holder); + })); } - public static ItemHolder getRandomNormalReward() + public int getLuckyGameCount() { - return _fortuneReadingTicketRewards.get(Rnd.get(_fortuneReadingTicketRewards.size())); + return _luckyGame.size(); } - public static ItemHolder getRandomLuxuryReward() + public LuckyGameDataHolder getLuckyGameDataByIndex(int index) { - return _luxuryFortuneReadingTicketRewards.get(Rnd.get(_luxuryFortuneReadingTicketRewards.size())); + return _luckyGame.get(index); } - public static ItemHolder getRandomRareReward() + public int increaseGame() { - return _rareLuxuryFortuneReadingTicketRewards.get(Rnd.get(_rareLuxuryFortuneReadingTicketRewards.size())); + return _serverPlay.incrementAndGet(); + } + + public int getServerPlay() + { + return _serverPlay.get(); } public static LuckyGameData getInstance() diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java new file mode 100644 index 0000000000..af1d82c1e1 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/enums/LuckyGameItemType.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameItemType +{ + COMMON(1), + UNIQUE(2), + RARE(3); + + private final int _clientId; + + LuckyGameItemType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.java new file mode 100644 index 0000000000..5a974d05d0 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/enums/LuckyGameResultType.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 com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameResultType +{ + INVALID_CAPACITY(-2), + INVALID_ITEM_COUNT(-1), + DISABLED(0), + SUCCESS(1); + + private final int _clientId; + + private LuckyGameResultType(int clientId) + { + _clientId = clientId; + } + + public int getClientId() + { + return _clientId; + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/enums/LuckyGameType.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/enums/LuckyGameType.java new file mode 100644 index 0000000000..f8f7938727 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/enums/LuckyGameType.java @@ -0,0 +1,27 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.enums; + +/** + * @author Sdw + */ +public enum LuckyGameType +{ + NONE, + NORMAL, + LUXURY +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java new file mode 100644 index 0000000000..5d2fbfb7b8 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/holders/ItemPointHolder.java @@ -0,0 +1,53 @@ +/* + * 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 com.l2jmobius.gameserver.model.holders; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class ItemPointHolder extends ItemHolder +{ + private final int _points; + + public ItemPointHolder(StatsSet params) + { + this(params.getInt("id"), params.getLong("count"), params.getInt("points")); + } + + public ItemPointHolder(int id, long count, int points) + { + super(id, count); + _points = points; + } + + /** + * Gets the point. + * @return the number of point to get the item + */ + public int getPoints() + { + return _points; + } + + @Override + public String toString() + { + return "[" + getClass().getSimpleName() + "] ID: " + getId() + ", count: " + getCount() + ", points: " + _points; + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java new file mode 100644 index 0000000000..43e93e30c5 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/holders/LuckyGameDataHolder.java @@ -0,0 +1,102 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.model.holders; + +import java.util.ArrayList; +import java.util.List; + +import com.l2jmobius.gameserver.model.StatsSet; + +/** + * @author Sdw + */ +public class LuckyGameDataHolder +{ + final private int _index; + final private int _turningPoints; + final private List _commonRewards = new ArrayList<>(); + final private List _uniqueRewards = new ArrayList<>(); + final private List _modifyRewards = new ArrayList<>(); + private int _minModifyRewardGame; + private int _maxModifyRewardGame; + + public LuckyGameDataHolder(StatsSet params) + { + _index = params.getInt("index"); + _turningPoints = params.getInt("turning_point"); + } + + public void addCommonReward(ItemChanceHolder item) + { + _commonRewards.add(item); + } + + public void addUniqueReward(ItemPointHolder item) + { + _uniqueRewards.add(item); + } + + public void addModifyReward(ItemChanceHolder item) + { + _modifyRewards.add(item); + } + + public List getCommonReward() + { + return _commonRewards; + } + + public List getUniqueReward() + { + return _uniqueRewards; + } + + public List getModifyReward() + { + return _modifyRewards; + } + + public void setMinModifyRewardGame(int minModifyRewardGame) + { + _minModifyRewardGame = minModifyRewardGame; + } + + public void setMaxModifyRewardGame(int maxModifyRewardGame) + { + _maxModifyRewardGame = maxModifyRewardGame; + } + + public int getMinModifyRewardGame() + { + return _minModifyRewardGame; + } + + public int getMaxModifyRewardGame() + { + return _maxModifyRewardGame; + } + + public int getIndex() + { + return _index; + } + + public int getTurningPoints() + { + return _turningPoints; + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java index 7698c1f912..fd1fb41f5f 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/variables/PlayerVariables.java @@ -57,6 +57,8 @@ public class PlayerVariables extends AbstractVariables public static final String REVELATION_SKILL_1_DUAL_CLASS = "DualclassRevelationSkill1"; public static final String REVELATION_SKILL_2_DUAL_CLASS = "DualclassRevelationSkill2"; public static final String EXTEND_DROP = "EXTEND_DROP"; + public static final String FORTUNE_TELLING_VARIABLE = "FortuneTelling"; + public static final String FORTUNE_TELLING_BLACK_CAT_VARIABLE = "FortuneTellingBlackCat"; private final int _objectId; diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index 54f6de56d3..4b6e53c14e 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -69,6 +69,8 @@ import com.l2jmobius.gameserver.network.clientpackets.dailymission.RequestTodoLi import com.l2jmobius.gameserver.network.clientpackets.ensoul.RequestItemEnsoul; import com.l2jmobius.gameserver.network.clientpackets.faction.RequestUserFactionInfo; import com.l2jmobius.gameserver.network.clientpackets.friend.RequestFriendDetailInfo; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGamePlay; +import com.l2jmobius.gameserver.network.clientpackets.luckygame.RequestLuckyGameStartInfo; import com.l2jmobius.gameserver.network.clientpackets.mentoring.ConfirmMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeAdd; import com.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeWaitingList; @@ -329,8 +331,8 @@ public enum ExIncomingPackets implements IIncomingPackets REQUEST_ABILITY_WND_OPEN(0xEE, RequestAbilityWndOpen::new, ConnectionState.IN_GAME), REQUEST_ABILITY_WND_CLOSE(0xEF, RequestAbilityWndClose::new, ConnectionState.IN_GAME), EX_PC_CAFE_REQUEST_OPEN_WINDOW_WITHOUT_NPC(0xF0, ExPCCafeRequestOpenWindowWithoutNPC::new, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_START_INFO(0xF1, null, ConnectionState.IN_GAME), - REQUEST_LUCKY_GAME_PLAY(0xF2, null, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_START_INFO(0xF1, RequestLuckyGameStartInfo::new, ConnectionState.IN_GAME), + REQUEST_LUCKY_GAME_PLAY(0xF2, RequestLuckyGamePlay::new, ConnectionState.IN_GAME), NOTIFY_TRAINING_ROOM_END(0xF3, null, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_PUSH_ONE(0xF4, RequestNewEnchantPushOne::new, ConnectionState.IN_GAME), REQUEST_NEW_ENCHANT_REMOVE_ONE(0xF5, RequestNewEnchantRemoveOne::new, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java index 72f40dcba6..1e48d2cfb6 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGamePlay.java @@ -16,30 +16,169 @@ */ package com.l2jmobius.gameserver.network.clientpackets.luckygame; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map.Entry; + import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.commons.util.CommonUtil; +import com.l2jmobius.commons.util.Rnd; +import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; +import com.l2jmobius.gameserver.datatables.ItemTable; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.LuckyGameDataHolder; +import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; +import com.l2jmobius.gameserver.model.variables.PlayerVariables; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; +import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; import com.l2jmobius.gameserver.network.serverpackets.luckygame.ExBettingLuckyGameResult; /** - * @author Mobius + * @author Sdw */ public class RequestLuckyGamePlay implements IClientIncomingPacket { - private int _type; - private int _count; + private static final int FORTUNE_READING_TICKET = 23767; + private static final int LUXURY_FORTUNE_READING_TICKET = 23768; + private LuckyGameType _type; + private int _reading; @Override public boolean read(L2GameClient client, PacketReader packet) { - _type = packet.readD(); // luxury = 2, normal = 1 - _count = packet.readD(); // count + final int type = CommonUtil.constrain(packet.readD(), 0, LuckyGameType.values().length); + _type = LuckyGameType.values()[type]; + _reading = CommonUtil.constrain(packet.readD(), 0, 50); // max play is 50 return true; } @Override public void run(L2GameClient client) { - client.getActiveChar().sendPacket(new ExBettingLuckyGameResult(client.getActiveChar(), _type, _count)); + final L2PcInstance player = client.getActiveChar(); + if (player == null) + { + return; + } + + final int index = _type == LuckyGameType.LUXURY ? 102 : 2; // move to event config + + final LuckyGameDataHolder holder = LuckyGameData.getInstance().getLuckyGameDataByIndex(index); + if (holder == null) + { + return; + } + + final long tickets = _type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1); + if (tickets < _reading) + { + player.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + int playCount = player.getVariables().getInt(PlayerVariables.FORTUNE_TELLING_VARIABLE, 0); + boolean blackCat = player.getVariables().getBoolean(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, false); + final EnumMap> rewards = new EnumMap<>(LuckyGameItemType.class); + for (int i = 0; i < _reading; i++) + { + final double chance = 100 * Rnd.nextDouble(); + double totalChance = 0; + + for (ItemChanceHolder item : holder.getCommonReward()) + { + totalChance += item.getChance(); + if (totalChance >= chance) + { + rewards.computeIfAbsent(LuckyGameItemType.COMMON, k -> new ArrayList<>()).add(item); + break; + } + } + playCount++; + if ((playCount >= holder.getMinModifyRewardGame()) && (playCount <= holder.getMaxModifyRewardGame()) && !blackCat) + { + final List modifyReward = holder.getModifyReward(); + final double chanceModify = 100 * Rnd.nextDouble(); + totalChance = 0; + + for (ItemChanceHolder item : modifyReward) + { + totalChance += item.getChance(); + if (totalChance >= chanceModify) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(item); + blackCat = true; + break; + } + } + + if (playCount == holder.getMaxModifyRewardGame()) + { + rewards.computeIfAbsent(LuckyGameItemType.RARE, k -> new ArrayList<>()).add(modifyReward.get(Rnd.get(modifyReward.size()))); + blackCat = true; + } + } + } + + final int totalWeight = rewards.values().stream().mapToInt(list -> list.stream().mapToInt(item -> ItemTable.getInstance().getTemplate(item.getId()).getWeight()).sum()).sum(); + + // Check inventory capacity + if ((rewards.size() > 0) && (!player.getInventory().validateCapacity(rewards.size()) || !player.getInventory().validateWeight(totalWeight))) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_CAPACITY : ExBettingLuckyGameResult.NORMAL_INVALID_CAPACITY); + player.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); + return; + } + + if (!player.destroyItemByItemId("LuckyGame", _type == LuckyGameType.LUXURY ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _reading, player, true)) + { + player.sendPacket(_type == LuckyGameType.LUXURY ? ExBettingLuckyGameResult.LUXURY_INVALID_ITEM_COUNT : ExBettingLuckyGameResult.NORMAL_INVALID_ITEM_COUNT); + return; + } + + for (int i = 0; i < _reading; i++) + { + final int serverGameNumber = LuckyGameData.getInstance().increaseGame(); + holder.getUniqueReward().stream().filter(reward -> reward.getPoints() == serverGameNumber).forEach(item -> rewards.computeIfAbsent(LuckyGameItemType.UNIQUE, k -> new ArrayList<>()).add(item)); + } + + player.sendPacket(new ExBettingLuckyGameResult(LuckyGameResultType.SUCCESS, _type, rewards, (int) (_type == LuckyGameType.LUXURY ? player.getInventory().getInventoryItemCount(LUXURY_FORTUNE_READING_TICKET, -1) : player.getInventory().getInventoryItemCount(FORTUNE_READING_TICKET, -1)))); + + final InventoryUpdate iu = new InventoryUpdate(); + for (Entry> reward : rewards.entrySet()) + { + for (ItemHolder r : reward.getValue()) + { + final L2ItemInstance item = player.addItem("LuckyGame", r.getId(), r.getCount(), player, true); + iu.addItem(item); + if (reward.getKey() == LuckyGameItemType.UNIQUE) + { + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); + sm.addPcName(player); + sm.addLong(r.getCount()); + sm.addItemName(item); + player.broadcastPacket(sm, 1000); + break; + } + + } + } + + player.sendInventoryUpdate(iu); + + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_VARIABLE, playCount >= 50 ? (playCount - 50) : playCount); + if (blackCat && (playCount < 50)) + { + player.getVariables().set(PlayerVariables.FORTUNE_TELLING_BLACK_CAT_VARIABLE, true); + } } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java new file mode 100644 index 0000000000..e39f110a76 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/luckygame/RequestLuckyGameStartInfo.java @@ -0,0 +1,39 @@ +/* + * 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 com.l2jmobius.gameserver.network.clientpackets.luckygame; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket; + +/** + * @author Sdw + */ +public class RequestLuckyGameStartInfo implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return true; + } + + @Override + public void run(L2GameClient client) + { + + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java index 32d7ebc372..d36f6bb0c3 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExBettingLuckyGameResult.java @@ -16,121 +16,69 @@ */ package com.l2jmobius.gameserver.network.serverpackets.luckygame; -import java.util.ArrayList; +import java.util.EnumMap; import java.util.List; +import java.util.Map.Entry; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.data.xml.impl.LuckyGameData; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameItemType; +import com.l2jmobius.gameserver.enums.LuckyGameResultType; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.model.holders.ItemHolder; -import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.network.OutgoingPackets; -import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; -import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** - * @author Mobius + * @author Sdw */ public class ExBettingLuckyGameResult implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _count = 0; - private int _type = 0; - private final L2PcInstance _activeChar; + public static final ExBettingLuckyGameResult NORMAL_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_ITEM_COUNT = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_ITEM_COUNT, LuckyGameType.LUXURY); + public static final ExBettingLuckyGameResult NORMAL_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.NORMAL); + public static final ExBettingLuckyGameResult LUXURY_INVALID_CAPACITY = new ExBettingLuckyGameResult(LuckyGameResultType.INVALID_CAPACITY, LuckyGameType.LUXURY); - public ExBettingLuckyGameResult(L2PcInstance activeChar, int type, int count) + private final LuckyGameResultType _result; + private final LuckyGameType _type; + private final EnumMap> _rewards; + private final int _ticketCount; + private final int _size; + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type) { - _count = count; + _result = result; _type = type; - _activeChar = activeChar; + _rewards = new EnumMap<>(LuckyGameItemType.class); + _ticketCount = 0; + _size = 0; + } + + public ExBettingLuckyGameResult(LuckyGameResultType result, LuckyGameType type, EnumMap> rewards, int ticketCount) + { + _result = result; + _type = type; + _rewards = rewards; + _ticketCount = ticketCount; + _size = (int) rewards.values().stream().mapToLong(i -> i.stream().count()).sum(); } @Override public boolean write(PacketWriter packet) { - // Calculate rewards - final List rewards = new ArrayList<>(); - int totalWeight = 0; - for (int rewardCounter = 0; rewardCounter < _count; rewardCounter++) - { - if (Rnd.get(3) == 0) // 1 out of 3 chance - { - ItemHolder reward = null; - if (_type == 2) - { - if (_count >= 40) - { - reward = LuckyGameData.getRandomRareReward(); - } - else - { - reward = LuckyGameData.getRandomLuxuryReward(); - } - } - else - { - reward = LuckyGameData.getRandomNormalReward(); - } - rewards.add(reward); - totalWeight += new L2ItemInstance(reward.getId()).getItem().getWeight() * reward.getCount(); - } - } - - // Check inventory capacity - if ((rewards.size() > 0) && (!_activeChar.getInventory().validateCapacity(rewards.size()) || !_activeChar.getInventory().validateWeight(totalWeight))) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_EITHER_FULL_OR_OVERWEIGHT); - return false; - } - - if (_activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1) < _count) - { - _activeChar.sendPacket(new ExStartLuckyGame(_activeChar, _type)); - _activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_TICKETS); - return false; - } - - // Remove tickets - _activeChar.getInventory().destroyItemByItemId("FortuneTelling", _type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, _count, _activeChar, "FortuneTelling"); - OutgoingPackets.EX_BETTING_LUCKY_GAME_RESULT.writeId(packet); - packet.writeD(0x01); // 0 disabled, 1 enabled - packet.writeD(0x01); // ? - packet.writeD((int) _activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1)); // Count remaining tickets - - if (rewards.size() > 0) + packet.writeD(_result.getClientId()); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); + packet.writeD(_size); + for (Entry> reward : _rewards.entrySet()) { - packet.writeD(rewards.size()); - for (ItemHolder reward : rewards) + for (ItemHolder item : reward.getValue()) { - packet.writeD(0x02); // normal = 1, rare = 2 (forcing 2) - packet.writeD(reward.getId()); - packet.writeD((int) reward.getCount()); - final SystemMessage sm; - if (_type == 2) - { - _activeChar.addItem("LuxuryFortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_IN_THE_LUXURY_FORTUNE_READING); - } - else - { - _activeChar.addItem("FortuneTelling", reward, _activeChar, false); - sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_C1_HAS_OBTAINED_S2_OF_S3_THROUGH_FORTUNE_READING); - } - sm.addPcName(_activeChar); - sm.addLong(reward.getCount()); - sm.addItemName(new L2ItemInstance(reward.getId())); - _activeChar.broadcastPacket(sm, 1000); + packet.writeD(reward.getKey().getClientId()); + packet.writeD(item.getId()); + packet.writeD((int) item.getCount()); } } - else - { - packet.writeD(0x00); - } return true; } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java index 4d58f5d294..233363fde2 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/luckygame/ExStartLuckyGame.java @@ -17,32 +17,30 @@ package com.l2jmobius.gameserver.network.serverpackets.luckygame; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.enums.LuckyGameType; import com.l2jmobius.gameserver.network.OutgoingPackets; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; /** - * @author Mobius + * @author Sdw */ public class ExStartLuckyGame implements IClientOutgoingPacket { - private static final int FORTUNE_READING_TICKET = 23767; - private static final int LUXURY_FORTUNE_READING_TICKET = 23768; - private int _type = 0; - private int _count = 0; + private final LuckyGameType _type; + private final int _ticketCount; - public ExStartLuckyGame(L2PcInstance activeChar, int type) + public ExStartLuckyGame(LuckyGameType type, long ticketCount) { _type = type; - _count = (int) activeChar.getInventory().getInventoryItemCount(_type == 2 ? LUXURY_FORTUNE_READING_TICKET : FORTUNE_READING_TICKET, -1); + _ticketCount = (int) ticketCount; } @Override public boolean write(PacketWriter packet) { OutgoingPackets.EX_START_LUCKY_GAME.writeId(packet); - packet.writeD(_type); - packet.writeD(_count); + packet.writeD(_type.ordinal()); + packet.writeD(_ticketCount); return true; } }