Unhardcoded Letter Collector rewards.

Thanks to Index.
This commit is contained in:
MobiusDevelopment
2022-06-09 15:59:40 +00:00
parent f41d29758e
commit 3000820cdb
42 changed files with 2956 additions and 1156 deletions

View File

@@ -16,22 +16,122 @@
*/
package events.LetterCollector;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.w3c.dom.Document;
import org.l2jmobius.commons.util.IXmlReader;
import org.l2jmobius.gameserver.instancemanager.events.LetterCollectorManager;
import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.events.EventType;
import org.l2jmobius.gameserver.model.events.ListenerRegisterType;
import org.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
import org.l2jmobius.gameserver.model.events.annotations.RegisterType;
import org.l2jmobius.gameserver.model.events.impl.creature.player.OnPlayerLogin;
import org.l2jmobius.gameserver.model.holders.ItemChanceHolder;
import org.l2jmobius.gameserver.model.holders.ItemHolder;
import org.l2jmobius.gameserver.model.quest.LongTimeEvent;
import org.l2jmobius.gameserver.network.serverpackets.ExLetterCollectorUI;
/**
* @author Mobius
*/
public class LetterCollector extends LongTimeEvent
public class LetterCollector extends LongTimeEvent implements IXmlReader
{
private LetterCollector()
{
if (isEventPeriod())
{
load();
LetterCollectorManager.getInstance().init();
}
}
public void reloadRewards()
{
LetterCollectorManager.getInstance().resetField();
load();
}
@Override
public synchronized void load()
{
parseDatapackFile("data/scripts/events/LetterCollector/rewards.xml");
}
@Override
public void parseDocument(Document doc, File f)
{
final AtomicInteger minimumLevel = new AtomicInteger();
final AtomicInteger maximumLevel = new AtomicInteger();
final Map<String, Integer> letters = new HashMap<>();
forEach(doc, "list", listNode ->
{
forEach(listNode, "params", paramNode ->
{
forEach(paramNode, "minimum", minimumLevelNode -> minimumLevel.set(new StatSet(parseAttributes(minimumLevelNode)).getInt("level")));
forEach(paramNode, "maximum", maximumLevelNode -> maximumLevel.set(new StatSet(parseAttributes(maximumLevelNode)).getInt("level")));
});
forEach(listNode, "letters", letterNode -> forEach(letterNode, "item", itemNode ->
{
StatSet letterSet = new StatSet(parseAttributes(itemNode));
letters.put(letterSet.getString("name"), letterSet.getInt("id"));
}));
forEach(listNode, "reward", rewardNode ->
{
final int id = new StatSet(parseAttributes(rewardNode)).getInt("id");
final AtomicReference<List<ItemHolder>> word = new AtomicReference<>(new ArrayList<>());
final AtomicReference<List<ItemChanceHolder>> rewards = new AtomicReference<>(new ArrayList<>());
AtomicBoolean needToSumAllChance = new AtomicBoolean(false);
AtomicReference<Double> chanceSum = new AtomicReference<>(0.0);
forEach(rewardNode, "word", wordNode ->
{
String[] letter = wordNode.getTextContent().trim().split(";");
for (String token : letter)
{
int count = 1;
for (ItemHolder check : word.get())
{
if (check.getId() == letters.get(token))
{
count = Math.toIntExact(check.getCount() + 1);
word.get().remove(check);
break;
}
}
word.get().add(new ItemHolder(letters.get(token), count));
}
});
forEach(rewardNode, "rewards", rewardsNode ->
{
needToSumAllChance.set(new StatSet(parseAttributes(rewardsNode)).getBoolean("sumChances"));
forEach(rewardsNode, "item", itemNode ->
{
StatSet itemSet = new StatSet(parseAttributes(itemNode));
final double chance = itemSet.getDouble("chance");
if (needToSumAllChance.get())
{
chanceSum.set(chanceSum.get() + chance);
}
rewards.get().add(new ItemChanceHolder(itemSet.getInt("id"), chance, itemSet.getLong("count"), (byte) itemSet.getInt("enchantLevel", 0)));
});
});
LetterCollectorManager lcm = LetterCollectorManager.getInstance();
lcm.addWords(id, word.get());
lcm.addRewards(id, new LetterCollectorManager.LetterCollectorRewardHolder(rewards.get(), chanceSum.get() == 0d ? 100d : chanceSum.get()));
lcm.setLetters(letters);
lcm.setMinLevel(minimumLevel.get());
lcm.setMaxLevel(maximumLevel.get());
});
});
}
@RegisterEvent(EventType.ON_PLAYER_LOGIN)
@@ -46,7 +146,7 @@ public class LetterCollector extends LongTimeEvent
final Player player = event.getPlayer();
if (player != null)
{
player.sendPacket(ExLetterCollectorUI.STATIC_PACKET);
player.sendPacket(new ExLetterCollectorUI(player));
}
}

View File

@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<event name="Letter Collector" active="30 06 2021-29 07 2029" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../xsd/eventConfig.xsd">
<!-- Minimum level (5) also set at ExLetterCollectorUI.java -->
<!-- Rewards and items set at ExLetterCollectorTakeReward.java -->
<droplist>
<add item="3875" min="1" max="1" chance="1%" minLevel="5" /> <!-- Letter Collector's A -->
<add item="3877" min="1" max="1" chance="1%" minLevel="5" /> <!-- Letter Collector's E -->

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="rewards.xsd">
<params>
<minimum level="5" />
<maximum level="-1" /> <!-- -1 = no limit -->
</params>
<letters>
<!-- name of letter, for using down / id of this letter -->
<item name="A" id="3875" />
<item name="E" id="3877" />
<item name="G" id="3879" />
<item name="I" id="3881" />
<item name="L" id="3882" />
<item name="N" id="3883" />
<item name="R" id="3885" />
<item name="M" id="34956" />
<item name="S" id="3886" />
<item name="T" id="3886" />
<item name="H" id="3880" />
<item name="II" id="3888" />
<item name="D" id="92021" />
<item name="K" id="93412" />
<item name="U" id="93413" />
</letters>
<!-- client id -->
<reward id="0">
<!-- split letter with ";" / LINEAGE II -> L;I;N;E;A;G;E;II -->
<word>L;I;N;E;A;G;E;II</word> <!-- LINEAGE II -->
<!-- sumChances - sum item chances cumulatively -->
<rewards sumChances="true">
<!-- item id; count; chance; / id="-1" = no reward -->
<item id="49683" count="1" chance="5" /> <!-- Talisman of Baium -->
<item id="91119" count="1" chance="5" /> <!-- Ignis' Necklace -->
<item id="91117" count="1" chance="5" /> <!-- Nebula's Necklace -->
<item id="91121" count="1" chance="5" /> <!-- Procella's Necklace -->
<item id="91123" count="1" chance="5" /> <!-- Petram's Necklace -->
<item id="91952" count="1" chance="5" /> <!-- Ring of Insolance -->
<item id="91953" count="1" chance="5" /> <!-- Dragon Valley's Earring -->
<item id="91035" count="1" chance="15" /> <!-- Water Spirit Ore -->
<item id="91036" count="1" chance="15" /> <!-- Fire Spirit Ore -->
<item id="91037" count="1" chance="15" /> <!-- Wind Spirit Ore -->
<item id="91038" count="1" chance="15" /> <!-- Earth Spirit Ore -->
<item id="91641" count="1" chance="30" /> <!-- Sayha's Blessing -->
<item id="49674" count="1" chance="30" /> <!-- XP Growth Scroll -->
<item id="90907" count="1" chance="30" /> <!-- Soulshot Ticket -->
<item id="91757" count="1" chance="30" /> <!-- Magic Lamp Charging Potion -->
<item id="91974" count="1" chance="30" /> <!-- HP Recovery Potion -->
<item id="3031" count="10" chance="30" /> <!-- Spirit Ore -->
</rewards>
</reward>
<reward id="1">
<word>D;E;A;T;H</word> <!-- DEATH -->
<rewards sumChances="true">
<item id="91012" count="1" chance="5" /> <!-- Top-grade A-grade Weapon Pack -->
<item id="93459" count="1" chance="5" /> <!-- A-grade Armor Pack - Majestic Equipment -->
<item id="93460" count="1" chance="5" /> <!-- A-grade Armor Pack - Equipment of Nightmare -->
<item id="93461" count="1" chance="5" /> <!-- A-grade Armor Pack - Tallum Equipment -->
<item id="93462" count="1" chance="5" /> <!-- A-grade Armor Pack - Dark Crystal Equipment -->
<item id="90015" count="1" chance="5" /> <!-- Top-grade Life Stone - Weapon -->
<item id="93100" count="1" chance="5" /> <!-- Mid-grade Life Stone Shield / Sigil -->
<item id="91938" count="1" chance="5" /> <!-- Primeval Isle's Time Stone -->
<item id="93699" count="1" chance="5" /> <!-- Charging Stone of Random Crafting - 1 charge -->
<item id="91641" count="1" chance="5" /> <!-- Sayha's Blessing -->
<item id="49674" count="1" chance="5" /> <!-- XP Growth Scroll -->
<item id="90907" count="1" chance="5" /> <!-- Soulshot Ticket -->
<item id="91757" count="1" chance="5" /> <!-- Magic Lamp Charging Potion -->
<item id="91974" count="10" chance="5" /> <!-- HP Recovery Potion -->
<item id="3031" count="10" chance="5" /> <!-- Spirit Ore -->
</rewards>
</reward>
<reward id="2">
<word>K;N;I;G;H;T</word> <!-- KNIGHT -->
<rewards sumChances="true">
<item id="93103" count="1" chance="5" /> <!-- Spellbook: Divine Beam -->
<item id="92401" count="1" chance="5" /> <!-- Spellbook: White Guardian -->
<item id="91945" count="1" chance="5" /> <!-- Book of Shadows -->
<item id="91944" count="1" chance="5" /> <!-- Book of Light -->
<item id="91943" count="1" chance="15" /> <!-- Crystal of Shadows -->
<item id="91942" count="1" chance="15" /> <!-- Crystal of Light -->
<item id="8619" count="1" chance="15" /> <!-- Buff Expansion Book Lv. 2 -->
<item id="8620" count="1" chance="15" /> <!-- Buff Expansion Book Lv. 3 -->
<item id="90045" count="1" chance="15" /> <!-- Magical Tablet -->
<item id="91641" count="1" chance="30" /> <!-- Sayha's Blessing -->
<item id="49674" count="1" chance="30" /> <!-- XP Growth Scroll -->
<item id="90907" count="5" chance="30" /> <!-- Soulshot Ticket -->
<item id="91757" count="1" chance="30" /> <!-- Magic Lamp Charging Potion -->
<item id="91974" count="10" chance="30" /> <!-- HP Recovery Potion -->
<item id="3031" count="10" chance="30" /> <!-- Spirit Ore -->
</rewards>
</reward>
<reward id="3">
<word>S;U;M;M;E;R</word> <!-- SUMMER -->
<rewards sumChances="true">
<item id="93976" count="1" chance="5" /> <!-- Blessed Scroll: Enchant A-grade Weapon -->
<item id="93977" count="1" chance="5" /> <!-- Blessed Scroll: Enchant A-grade Armor -->
<item id="729" count="1" chance="5" /> <!-- Scroll: Enchant A-grade Weapon -->
<item id="730" count="1" chance="5" /> <!-- Scroll: Enchant A-grade Armor -->
<item id="947" count="1" chance="5" /> <!-- Scroll: Enchant B-grade Weapon -->
<item id="948" count="1" chance="5" /> <!-- Scroll: Enchant B-grade Armor -->
<item id="91967" count="1" chance="5" /> <!-- Scroll: Enchant Dragon Valley's Earring -->
<item id="91966" count="1" chance="5" /> <!-- Scroll: Enchant Ring of Insolance -->
<item id="91641" count="1" chance="5" /> <!-- Sayha's Blessing -->
<item id="91780" count="1" chance="5" /> <!-- Battle Scroll -->
<item id="93486" count="1" chance="5" /> <!-- Combat Scroll -->
<item id="49674" count="1" chance="5" /> <!-- XP Growth Scroll -->
<item id="90907" count="1" chance="5" /> <!-- Soulshot Ticket -->
<item id="1538" count="1" chance="5" /> <!-- Improved Scroll of Escape -->
<item id="91757" count="1" chance="5" /> <!-- Magic Lamp Charging Potion -->
<item id="91974" count="10" chance="5" /> <!-- HP Recovery Potion -->
<item id="3031" count="10" chance="5" /> <!-- Spirit Ore -->
</rewards>
</reward>
</list>

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="list" type="listType"/>
<xs:complexType name="minimumType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="level"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="maximumType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="level"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="paramsType">
<xs:sequence>
<xs:element type="minimumType" name="minimum"/>
<xs:element type="maximumType" name="maximum"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="name" use="optional"/>
<xs:attribute type="xs:string" name="id" use="optional"/>
<xs:attribute type="xs:string" name="count" use="optional"/>
<xs:attribute type="xs:string" name="chance" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="lettersType">
<xs:sequence>
<xs:element type="itemType" name="item" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="rewardsType">
<xs:sequence>
<xs:element type="itemType" name="item" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:string" name="sumChances"/>
</xs:complexType>
<xs:complexType name="rewardType">
<xs:sequence>
<xs:element type="xs:string" name="word"/>
<xs:element type="rewardsType" name="rewards"/>
</xs:sequence>
<xs:attribute type="xs:string" name="id"/>
</xs:complexType>
<xs:complexType name="listType">
<xs:sequence>
<xs:element type="paramsType" name="params"/>
<xs:element type="lettersType" name="letters"/>
<xs:element type="rewardType" name="reward" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>