Compare commits

...

2 Commits

Author SHA1 Message Date
Ponk
799cb97564 Merge pull request #217 from P0nk/fix/210-clean-slate-scroll #minor
Fix able to gain infinite slots with clean slate scroll
2024-02-05 08:39:25 +01:00
P0nk
851b57e8ef Fix able to gain infinite slots with clean slate scroll
And remove a GM config option.
Thanks Crabo for the suggested solution.
2024-02-05 08:34:36 +01:00
4 changed files with 55 additions and 31 deletions

View File

@@ -347,7 +347,6 @@ server:
USE_PERFECT_SCROLLING: false #Scrolls doesn't use slots upon failure. USE_PERFECT_SCROLLING: false #Scrolls doesn't use slots upon failure.
USE_ENHANCED_CHSCROLL: false #Equips even more powerful with chaos upgrade. USE_ENHANCED_CHSCROLL: false #Equips even more powerful with chaos upgrade.
USE_ENHANCED_CRAFTING: false #Apply chaos scroll on every equip crafted. USE_ENHANCED_CRAFTING: false #Apply chaos scroll on every equip crafted.
USE_ENHANCED_CLNSLATE: false #Clean slates can be applied to recover successfully used slots as well.
SCROLL_CHANCE_ROLLS: 1 #Number of rolls for success on a scroll, set 1 for default. SCROLL_CHANCE_ROLLS: 1 #Number of rolls for success on a scroll, set 1 for default.
CHSCROLL_STAT_RATE: 1 #Number of rolls of stat upgrade on a successfully applied chaos scroll, set 1 for default. CHSCROLL_STAT_RATE: 1 #Number of rolls of stat upgrade on a successfully applied chaos scroll, set 1 for default.
CHSCROLL_STAT_RANGE: 6 #Stat upgrade range (-N, N) on chaos scrolls. CHSCROLL_STAT_RANGE: 6 #Stat upgrade range (-N, N) on chaos scrolls.

View File

@@ -195,7 +195,6 @@ public class ServerConfig {
public boolean USE_PERFECT_SCROLLING; public boolean USE_PERFECT_SCROLLING;
public boolean USE_ENHANCED_CHSCROLL; public boolean USE_ENHANCED_CHSCROLL;
public boolean USE_ENHANCED_CRAFTING; public boolean USE_ENHANCED_CRAFTING;
public boolean USE_ENHANCED_CLNSLATE;
public int SCROLL_CHANCE_ROLLS; public int SCROLL_CHANCE_ROLLS;
public int CHSCROLL_STAT_RATE; public int CHSCROLL_STAT_RATE;
public int CHSCROLL_STAT_RANGE; public int CHSCROLL_STAT_RANGE;

View File

@@ -25,8 +25,12 @@ import client.Character;
import client.Client; import client.Client;
import client.Skill; import client.Skill;
import client.SkillFactory; import client.SkillFactory;
import client.inventory.*; import client.inventory.Equip;
import client.inventory.Equip.ScrollResult; import client.inventory.Equip.ScrollResult;
import client.inventory.Inventory;
import client.inventory.InventoryType;
import client.inventory.Item;
import client.inventory.ModifyInventory;
import client.inventory.manipulator.InventoryManipulator; import client.inventory.manipulator.InventoryManipulator;
import constants.id.ItemId; import constants.id.ItemId;
import constants.inventory.ItemConstants; import constants.inventory.ItemConstants;
@@ -37,7 +41,6 @@ import tools.PacketCreator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @author Matze * @author Matze
@@ -50,8 +53,8 @@ public final class ScrollHandler extends AbstractPacketHandler {
if (c.tryacquireClient()) { if (c.tryacquireClient()) {
try { try {
p.readInt(); // whatever... p.readInt(); // whatever...
short slot = p.readShort(); short scrollSlot = p.readShort();
short dst = p.readShort(); short equipSlot = p.readShort();
byte ws = (byte) p.readShort(); byte ws = (byte) p.readShort();
boolean whiteScroll = false; // white scroll being used? boolean whiteScroll = false; // white scroll being used?
boolean legendarySpirit = false; // legendary spirit skill boolean legendarySpirit = false; // legendary spirit skill
@@ -61,24 +64,21 @@ public final class ScrollHandler extends AbstractPacketHandler {
ItemInformationProvider ii = ItemInformationProvider.getInstance(); ItemInformationProvider ii = ItemInformationProvider.getInstance();
Character chr = c.getPlayer(); Character chr = c.getPlayer();
Equip toScroll = (Equip) chr.getInventory(InventoryType.EQUIPPED).getItem(dst); Equip toScroll = (Equip) chr.getInventory(InventoryType.EQUIPPED).getItem(equipSlot);
Skill LegendarySpirit = SkillFactory.getSkill(1003); Skill LegendarySpirit = SkillFactory.getSkill(1003);
if (chr.getSkillLevel(LegendarySpirit) > 0 && dst >= 0) { if (chr.getSkillLevel(LegendarySpirit) > 0 && equipSlot >= 0) {
legendarySpirit = true; legendarySpirit = true;
toScroll = (Equip) chr.getInventory(InventoryType.EQUIP).getItem(dst); toScroll = (Equip) chr.getInventory(InventoryType.EQUIP).getItem(equipSlot);
} }
byte oldLevel = toScroll.getLevel(); byte oldLevel = toScroll.getLevel();
byte oldSlots = toScroll.getUpgradeSlots(); byte oldSlots = toScroll.getUpgradeSlots();
Inventory useInventory = chr.getInventory(InventoryType.USE); Inventory useInventory = chr.getInventory(InventoryType.USE);
Item scroll = useInventory.getItem(slot); Item scroll = useInventory.getItem(scrollSlot);
Item wscroll = null; Item wscroll = null;
if (ItemConstants.isCleanSlate(scroll.getItemId())) { if (ItemConstants.isCleanSlate(scroll.getItemId()) && !ii.canUseCleanSlate(toScroll)) {
Map<String, Integer> eqStats = ii.getEquipStats(toScroll.getItemId()); // clean slate issue found thanks to Masterrulax announceCannotScroll(c, legendarySpirit);
if (eqStats == null || eqStats.get("tuc") == 0) { return;
announceCannotScroll(c, legendarySpirit);
return;
}
} else if (!ItemConstants.isModifierScroll(scroll.getItemId()) && toScroll.getUpgradeSlots() < 1) { } else if (!ItemConstants.isModifierScroll(scroll.getItemId()) && toScroll.getUpgradeSlots() < 1) {
announceCannotScroll(c, legendarySpirit); // thanks onechord for noticing zero upgrade slots freezing Legendary Scroll UI announceCannotScroll(c, legendarySpirit); // thanks onechord for noticing zero upgrade slots freezing Legendary Scroll UI
return; return;
@@ -103,11 +103,6 @@ public final class ScrollHandler extends AbstractPacketHandler {
} }
} }
if (ItemConstants.isCleanSlate(scroll.getItemId()) && !ii.canUseCleanSlate(toScroll)) {
announceCannotScroll(c, legendarySpirit);
return;
}
Equip scrolled = (Equip) ii.scrollEquipWithId(toScroll, scroll.getItemId(), whiteScroll, 0, chr.isGM()); Equip scrolled = (Equip) ii.scrollEquipWithId(toScroll, scroll.getItemId(), whiteScroll, 0, chr.isGM());
ScrollResult scrollSuccess = Equip.ScrollResult.FAIL; // fail ScrollResult scrollSuccess = Equip.ScrollResult.FAIL; // fail
if (scrolled == null) { if (scrolled == null) {
@@ -141,7 +136,7 @@ public final class ScrollHandler extends AbstractPacketHandler {
if (scrollSuccess == Equip.ScrollResult.CURSE) { if (scrollSuccess == Equip.ScrollResult.CURSE) {
if (!ItemId.isWeddingRing(toScroll.getItemId())) { if (!ItemId.isWeddingRing(toScroll.getItemId())) {
mods.add(new ModifyInventory(3, toScroll)); mods.add(new ModifyInventory(3, toScroll));
if (dst < 0) { if (equipSlot < 0) {
Inventory inv = chr.getInventory(InventoryType.EQUIPPED); Inventory inv = chr.getInventory(InventoryType.EQUIPPED);
inv.lockInventory(); inv.lockInventory();
@@ -174,7 +169,7 @@ public final class ScrollHandler extends AbstractPacketHandler {
} }
c.sendPacket(PacketCreator.modifyInventory(true, mods)); c.sendPacket(PacketCreator.modifyInventory(true, mods));
chr.getMap().broadcastMessage(PacketCreator.getScrollEffect(chr.getId(), scrollSuccess, legendarySpirit, whiteScroll)); chr.getMap().broadcastMessage(PacketCreator.getScrollEffect(chr.getId(), scrollSuccess, legendarySpirit, whiteScroll));
if (dst < 0 && (scrollSuccess == Equip.ScrollResult.SUCCESS || scrollSuccess == Equip.ScrollResult.CURSE)) { if (equipSlot < 0 && (scrollSuccess == Equip.ScrollResult.SUCCESS || scrollSuccess == Equip.ScrollResult.CURSE)) {
chr.equipChanged(); chr.equipChanged();
} }
} finally { } finally {

View File

@@ -22,9 +22,16 @@
package server; package server;
import client.Character; import client.Character;
import client.*; import client.Client;
import client.Job;
import client.Skill;
import client.SkillFactory;
import client.autoban.AutobanFactory; import client.autoban.AutobanFactory;
import client.inventory.*; import client.inventory.Equip;
import client.inventory.Inventory;
import client.inventory.InventoryType;
import client.inventory.Item;
import client.inventory.WeaponType;
import config.YamlConfig; import config.YamlConfig;
import constants.id.ItemId; import constants.id.ItemId;
import constants.inventory.EquipSlot; import constants.inventory.EquipSlot;
@@ -35,19 +42,36 @@ import constants.skills.NightWalker;
import net.server.Server; import net.server.Server;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import provider.*; import provider.Data;
import provider.DataDirectoryEntry;
import provider.DataFileEntry;
import provider.DataProvider;
import provider.DataProviderFactory;
import provider.DataTool;
import provider.wz.WZFiles; import provider.wz.WZFiles;
import server.MakerItemFactory.MakerItemCreateEntry; import server.MakerItemFactory.MakerItemCreateEntry;
import server.life.LifeFactory; import server.life.LifeFactory;
import server.life.MonsterInformationProvider; import server.life.MonsterInformationProvider;
import tools.*; import tools.DatabaseConnection;
import tools.PacketCreator;
import tools.Pair;
import tools.Randomizer;
import tools.StringUtil;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
/** /**
* @author Matze * @author Matze
@@ -1025,9 +1049,16 @@ public class ItemInformationProvider {
Issue with clean slate found thanks to Masterrulax Issue with clean slate found thanks to Masterrulax
Vicious added in the clean slate check thanks to Crypter (CrypterDEV) Vicious added in the clean slate check thanks to Crypter (CrypterDEV)
*/ */
public boolean canUseCleanSlate(Equip nEquip) { public boolean canUseCleanSlate(Equip equip) {
Map<String, Integer> eqstats = this.getEquipStats(nEquip.getItemId()); Map<String, Integer> eqStats = getEquipStats(equip.getItemId());
return YamlConfig.config.server.USE_ENHANCED_CLNSLATE || nEquip.getUpgradeSlots() < (byte) (eqstats.get("tuc") + nEquip.getVicious()); if (eqStats == null || eqStats.get("tuc") == 0 ) {
return false;
}
int totalUpgradeCount = eqStats.get("tuc");
int freeUpgradeCount = equip.getUpgradeSlots();
int viciousCount = equip.getVicious();
int appliedScrollCount = equip.getLevel();
return freeUpgradeCount + appliedScrollCount < totalUpgradeCount + viciousCount;
} }
public Item scrollEquipWithId(Item equip, int scrollId, boolean usingWhiteScroll, int vegaItemId, boolean isGM) { public Item scrollEquipWithId(Item equip, int scrollId, boolean usingWhiteScroll, int vegaItemId, boolean isGM) {