Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save noaione/2eeda15d1fabe37248b2a8cc96c57c45 to your computer and use it in GitHub Desktop.
Save noaione/2eeda15d1fabe37248b2a8cc96c57c45 to your computer and use it in GitHub Desktop.
a patch for a custom server for certain turn-based rpg that kinda fix the pity system and make it customizable | head: bac849d72a282145109ab1bbd2e46b5261fe9315
From 4ef0a621d7b4aa91e81b254435ec1911eaf8e52c Mon Sep 17 00:00:00 2001
From: noaione <noaione0809@gmail.com>
Date: Wed, 3 Jan 2024 15:49:59 +0700
Subject: [PATCH] Rework gacha system and make it customizable
I would like someone smart enough with math to do the actual calculation
and re-rework the gacha system again :)
diff --git a/src/main/java/emu/lunarcore/Config.java b/src/main/java/emu/lunarcore/Config.java
index 48a5da5..c5c5f76 100644
--- a/src/main/java/emu/lunarcore/Config.java
+++ b/src/main/java/emu/lunarcore/Config.java
@@ -22,10 +22,11 @@ public class Config {
public HttpServerConfig httpServer = new HttpServerConfig(443);
public GameServerConfig gameServer = new GameServerConfig(23301);
-
+
public ServerOptions serverOptions = new ServerOptions();
public ServerTime serverTime = new ServerTime();
public ServerRates serverRates = new ServerRates();
+ public GachaSystem gachaSystem = new GachaSystem();
public LogOptions logOptions = new LogOptions();
public DownloadData downloadData = new DownloadData();
@@ -57,33 +58,33 @@ public class Config {
public String bindAddress = "0.0.0.0";
@SerializedName(value = "bindPort", alternate = {"port"})
public int bindPort;
-
+
// Will return bindAddress if publicAddress is null
public String publicAddress = "127.0.0.1";
// Will return bindPort if publicPort is null
public Integer publicPort;
-
+
public ServerConfig(int port) {
this.bindPort = port;
}
-
+
public String getPublicAddress() {
if (this.publicAddress != null && !this.publicAddress.isEmpty()) {
return this.publicAddress;
}
-
+
return this.bindAddress;
}
-
+
public int getPublicPort() {
if (this.publicPort != null && this.publicPort != 0) {
return this.publicPort;
}
-
+
return this.bindPort;
}
}
-
+
@Getter
public static class HttpServerConfig extends ServerConfig {
public boolean useSSL = true;
@@ -92,7 +93,7 @@ public class Config {
public HttpServerConfig(int port) {
super(port);
}
-
+
public String getDisplayAddress() {
return (useSSL ? "https" : "http") + "://" + getPublicAddress() + ":" + getPublicPort();
}
@@ -109,13 +110,13 @@ public class Config {
super(port);
}
}
-
- @Getter
+
+ @Getter
public static class ServerTime {
public boolean spoofTime = false;
public Date spoofDate = new Date(1705276800000L); // January 15, 2024 12:00:00 AM (GMT)
}
-
+
@Getter
public static class ServerOptions {
public boolean autoCreateAccount = true;
@@ -129,19 +130,19 @@ public class Config {
public boolean autoUpgradeWorldLevel = true; // Automatically upgrades world level when the player reaches a certain TB level
public String language = "EN";
public Set<String> defaultPermissions = Set.of("*");
-
+
public ServerProfile serverFriendInfo = new ServerProfile();
public WelcomeMail welcomeMail = new WelcomeMail();
-
+
public int getStaminaRecoveryRate() {
return staminaRecoveryRate > 0 ? staminaRecoveryRate : 1;
}
-
+
public int getStaminaReserveRecoveryRate() {
return staminaReserveRecoveryRate > 0 ? staminaReserveRecoveryRate : 1;
}
}
-
+
@Getter
public static class ServerRates {
public double exp = 1.0;
@@ -150,7 +151,32 @@ public class Config {
public double material = 1.0;
public double equip = 1.0;
}
-
+
+ // The gacha system.
+ // By default, we follow MHY own pity rates.
+ // At 90 pulls, you are guaranteed a 5 star.
+ // At every 10 pulls, you are guaranteed a 4 star.
+ // At 75 pity (for 5 star), your gacha rate is boosted until you get a 5 star or you hit the pity.
+ // ----
+ // Everytime you pull for dupe, you will earn a starglitter.
+ // - New cons: 8 starglitter
+ // - Max cons: 20 starglitter
+ // - New weapon: 5* 40, 4* 8, 3* 20 stardust
+ @Getter
+ public static class GachaSystem {
+ public int pity5 = 90;
+ public int pityWeapon5 = 80;
+ public int pity4 = 10;
+ public int boostRatePity = 75;
+ public int boostRateWeaponPity = 65;
+ public int consNew = 8;
+ public int consMax = 20;
+ public int consWeapon5 = 40;
+ public int consWeapon4 = 8;
+ // This is stardust and not starglitter
+ public int consWeapon3 = 20;
+ }
+
@Getter
public static class ServerProfile {
public String name = "Server";
@@ -161,14 +187,14 @@ public class Config {
public int displayAvatarId = 1001;
public int displayAvatarLevel = 1;
}
-
+
@Getter
public static class WelcomeMail {
public String title;
public String sender;
public String content;
public List<ItemParam> attachments;
-
+
public WelcomeMail() {
this.title = "Welcome to a LunarCore server";
this.sender = "Server";
@@ -182,7 +208,7 @@ public class Config {
);
}
}
-
+
@Getter
public static class LogOptions {
public boolean commands = true;
@@ -190,7 +216,7 @@ public class Config {
public boolean packets = false;
public boolean filterLoopingPackets = false;
}
-
+
@Getter
public static class DownloadData {
public String assetBundleUrl = null;
diff --git a/src/main/java/emu/lunarcore/LunarCore.java b/src/main/java/emu/lunarcore/LunarCore.java
index bcac72b..f5694a8 100644
--- a/src/main/java/emu/lunarcore/LunarCore.java
+++ b/src/main/java/emu/lunarcore/LunarCore.java
@@ -43,7 +43,7 @@ public class LunarCore {
private static LineReaderImpl reader;
@Getter private static boolean usingDumbTerminal;
-
+
private static long timeOffset = 0;
static {
@@ -70,9 +70,52 @@ public class LunarCore {
LunarCore.getLogger().info("Game version: " + GameConstants.VERSION);
boolean generateHandbook = true;
+ // Verify gacha system
+ LunarCore.getLogger().info("Verifying gacha system...");
+ emu.lunarcore.Config.GachaSystem gachaSystem = getConfig().getGachaSystem();
+ // Check if pity5 is more than 2
+ if (gachaSystem.getPity5() < 2) {
+ LunarCore.getLogger().error("`gachaSystem.pity5` must be at least 2.");
+ System.exit(1);
+ }
+ // Check if boostRatePity is more than 1
+ if (gachaSystem.getBoostRatePity() < 2) {
+ LunarCore.getLogger().error("`gachaSystem.boostRatePity` must be at least 1.");
+ System.exit(1);
+ }
+ // Check if boostRatePity is more than pity5
+ if (gachaSystem.getBoostRatePity() >= gachaSystem.getPity5()) {
+ LunarCore.getLogger().error("`gachaSystem.boostRatePity` must be less than `gachaSystem.pity5`.");
+ System.exit(1);
+ }
+ // Check if pity4 is more than 10 or less than 2
+ if (gachaSystem.getPity4() > 10 || gachaSystem.getPity4() < 2) {
+ LunarCore.getLogger().error("`gachaSystem.pity4` must be between 2 and 10.");
+ System.exit(1);
+ }
+ // Check if pity4 is more than pity5
+ if (gachaSystem.getPity4() >= gachaSystem.getPity5()) {
+ LunarCore.getLogger().error("`gachaSystem.pity4` must be less than `gachaSystem.pity5`.");
+ System.exit(1);
+ }
+ if (gachaSystem.getConsNew() < 1 || gachaSystem.getConsMax() < 1) {
+ LunarCore.getLogger().error("`gachaSystem.consNew` and `gachaSystem.consMax` must be at least 1.");
+ System.exit(1);
+ }
+ // Ensure that both consNew and consMax when multiplied by 2.5 does not have a remainder
+ if (gachaSystem.getConsNew() * 2.5 % 1 != 0 || gachaSystem.getConsMax() * 2.5 % 1 != 0) {
+ LunarCore.getLogger().error("`gachaSystem.consNew` and `gachaSystem.consMax` when multiplied by 2.5 must not have a remainder.");
+ System.exit(1);
+ }
+ // Check consWeapon5/4/3 is more than 1
+ if (gachaSystem.getConsWeapon5() < 1 || gachaSystem.getConsWeapon4() < 1 || gachaSystem.getConsWeapon3() < 1) {
+ LunarCore.getLogger().error("`gachaSystem.consWeapon5`, `gachaSystem.consWeapon4`, and `gachaSystem.consWeapon3` must be at least 1.");
+ System.exit(1);
+ }
+
// Load commands
LunarCore.commandManager = new CommandManager();
-
+
// Load plugin manager
LunarCore.pluginManager = new PluginManager();
@@ -138,7 +181,7 @@ public class LunarCore {
} catch (Exception exception) {
LunarCore.getLogger().error("Unable to start the game server.", exception);
}
-
+
// Hook into shutdown event
Runtime.getRuntime().addShutdownHook(new Thread(LunarCore::onShutdown));
@@ -186,12 +229,12 @@ public class LunarCore {
} catch (Exception e) {
// Ignored
}
-
+
// Sanity check
if (LunarCore.getConfig() == null) {
LunarCore.config = new Config();
}
-
+
// Save config
LunarCore.saveConfig();
}
@@ -203,7 +246,7 @@ public class LunarCore {
.setPrettyPrinting()
.serializeNulls()
.create();
-
+
file.write(gson.toJson(config));
} catch (Exception e) {
getLogger().error("Config save error");
@@ -211,7 +254,7 @@ public class LunarCore {
}
// Build Config
-
+
private static String getJarVersion() {
// Safely get the build config class without errors even if it hasnt been generated yet
try {
@@ -220,50 +263,50 @@ public class LunarCore {
} catch (Exception e) {
// Ignored
}
-
+
return "";
}
private static String getGitHash() {
// Use a string builder in case one of the build config fields are missing
StringBuilder builder = new StringBuilder();
-
+
// Safely get the build config class without errors even if it hasnt been generated yet
try {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Class<?> buildConfig = Class.forName(LunarCore.class.getPackageName() + ".BuildConfig");
-
+
String hash = buildConfig.getField("GIT_HASH").get(null).toString();
builder.append(hash);
-
+
String timestamp = buildConfig.getField("GIT_TIMESTAMP").get(null).toString();
long time = Long.parseLong(timestamp) * 1000;
builder.append(" (" + sf.format(new Date(time)) + ")");
} catch (Exception e) {
// Ignored
}
-
+
if (builder.isEmpty()) {
return "";
} else {
return builder.toString();
}
}
-
+
/**
* Returns the current server's time in milliseconds to send to the client. Can be used to spoof server time.
*/
public static long currentServerTime() {
return convertToServerTime(System.currentTimeMillis());
}
-
+
/**
* Converts a timestamp (in milliseconds) to the server time
*/
public static long convertToServerTime(long time) {
return time + timeOffset;
}
-
+
private static void updateServerTimeOffset() {
var timeOptions = LunarCore.getConfig().getServerTime();
if (timeOptions.isSpoofTime() && timeOptions.getSpoofDate() != null) {
diff --git a/src/main/java/emu/lunarcore/game/gacha/GachaRiggedDice.java b/src/main/java/emu/lunarcore/game/gacha/GachaRiggedDice.java
new file mode 100644
index 0000000..352b17c
--- /dev/null
+++ b/src/main/java/emu/lunarcore/game/gacha/GachaRiggedDice.java
@@ -0,0 +1,159 @@
+package emu.lunarcore.game.gacha;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * The following is a class implementation of the dice roll probability
+ *
+ * It use MHY own gacha rates to calculate the probability of getting a 5* or 4* character/weapon
+ *
+ * The following is the probability of getting a 5* character/weapon
+ * - 0.6% for character banner
+ * - 0.8% for weapon banner
+ *
+ * The following is the probability of getting a 4* character/weapon
+ * - 5.1% for character banner
+ * - 6.0% for weapon banner
+ */
+public class GachaRiggedDice {
+ // Won state from the rigged dice
+ public enum WonState {
+ // 5* character/weapon
+ SuperRare,
+ // 4* character/weapon
+ VeryRare,
+ // 3* weapon
+ Rare,
+ }
+
+ private double[] faces;
+ private PlayerGachaBannerInfo gachaInfo;
+ private GachaType gachaType;
+ private emu.lunarcore.Config.GachaSystem config;
+
+ public GachaRiggedDice(PlayerGachaBannerInfo info, GachaType type, emu.lunarcore.Config.GachaSystem config) {
+ this.gachaInfo = info;
+ this.gachaType = type;
+ this.config = config;
+ // 3 sided dice (3*, 4*, 5*)
+ // the dice include the probability of getting each rarity
+ // starting from 3* to 5*
+ // All of this number would be added up to 100%
+ // All numbers in percentage
+ if (type == GachaType.WeaponUp) {
+ // Weapon have different rates
+ this.faces = new double[]{93.2, 6.0, 0.8};
+ } else {
+ this.faces = new double[]{94.3, 5.1, 0.6};
+ }
+ }
+
+ public double makeRoll(double min, double max) {
+ return ThreadLocalRandom.current().nextDouble(max - min + 1) + min;
+ }
+
+ public double[] getFacesWithBoostRate() {
+ // Clone the faces
+ double[] newFaces = new double[faces.length];
+ System.arraycopy(faces, 0, newFaces, 0, faces.length);
+
+ // Check if the pity is high enough to boost the rate
+ int maxPity = getConfigMaxPity5();
+ if (this.gachaInfo.getPity5() < getConfigBoostRate()) {
+ // Nope, not high enough
+ return newFaces;
+ }
+
+ // High enough, let's boost the rate on the 5* character/weapon
+ // Convert baseline percentage to decimal
+ double baseline = newFaces[2];
+ double boostArea = maxPity - getConfigBoostRate();
+ double untilPity = (boostArea - (maxPity - this.gachaInfo.getPity5())) + 1;
+
+ double boostRate = 100 * (untilPity / (boostArea - 1));
+ double boostedRate = baseline + boostRate;
+ if (boostedRate >= 100) {
+ newFaces[0] = 0;
+ newFaces[1] = 0;
+ newFaces[2] = 100;
+ return newFaces;
+ }
+
+ // Adjust the rate by just subtracting the 5* rate
+ newFaces[2] = boostedRate;
+ double totalRate = 100.0;
+ double remainingRate = totalRate - boostedRate;
+
+ // Adjust the first face
+ if (remainingRate > newFaces[0]) {
+ // First face is exhausted
+ newFaces[0] = 0;
+ remainingRate -= newFaces[0];
+ } else {
+ // First face is not exhausted
+ newFaces[0] -= 100 - remainingRate;
+ }
+
+ // Adjust the second face
+ if (remainingRate > newFaces[1]) {
+ // First and second face is exhausted
+ newFaces[1] = 0;
+ return newFaces;
+ } else {
+ // Second face is not exhausted
+ newFaces[1] -= remainingRate;
+ return newFaces;
+ }
+ }
+
+ private int getConfigBoostRate() {
+ if (this.gachaType == GachaType.WeaponUp) {
+ return this.config.getBoostRateWeaponPity();
+ }
+ return this.config.getBoostRatePity();
+ }
+
+ private int getConfigMaxPity5() {
+ if (this.gachaType == GachaType.WeaponUp) {
+ return this.config.getPityWeapon5();
+ }
+ return this.config.getPity5();
+ }
+
+ public WonState roll() {
+ // Increase pity
+ this.gachaInfo.addPity4(1);
+ this.gachaInfo.addPity5(1);
+
+ // Do the dice roll without upgrading the pity
+ if (this.gachaInfo.getPity4() >= this.config.getPity4()) {
+ // Guaranteed 4*
+ this.gachaInfo.setPity4(0);
+ return WonState.VeryRare;
+ }
+
+ if (this.gachaInfo.getPity5() >= getConfigMaxPity5()) {
+ // Guaranteed 5*
+ this.gachaInfo.setPity5(0);
+ return WonState.SuperRare;
+ }
+
+ // Roll the dice
+ // Adjust for boost rate when the pity is high enough.
+ double myRoll = makeRoll(1d, 1000d);
+ double[] diceFacesAdjusted = getFacesWithBoostRate();
+
+ if (myRoll <= diceFacesAdjusted[2] * 10) {
+ // 5* character/weapon, reset pity 5 and keep pity 4
+ this.gachaInfo.setPity5(0);
+ return WonState.SuperRare;
+ } else if (myRoll <= (diceFacesAdjusted[2] + diceFacesAdjusted[1]) * 10) {
+ // 4* character/weapon, reset pity 4 and keep pity 5
+ this.gachaInfo.setPity4(0);
+ return WonState.VeryRare;
+ } else {
+ // 3* weapon, add pity 4 and 5
+ return WonState.Rare;
+ }
+ }
+}
diff --git a/src/main/java/emu/lunarcore/game/gacha/GachaService.java b/src/main/java/emu/lunarcore/game/gacha/GachaService.java
index 5bf0c38..878d63c 100644
--- a/src/main/java/emu/lunarcore/game/gacha/GachaService.java
+++ b/src/main/java/emu/lunarcore/game/gacha/GachaService.java
@@ -43,14 +43,14 @@ public class GachaService extends BaseGameService {
private int[] purpleWeapons = new int[] {21000, 21001, 21002, 21003, 21004, 21005, 21006, 21007, 21008, 21009, 21010, 21011, 21012, 21013, 21014, 21015, 21016, 21017, 21018, 21019, 21020};
private int[] blueWeapons = new int[] {20000, 20001, 20002, 20003, 20004, 20005, 20006, 20007, 20008, 20009, 20010, 20011, 20012, 20013, 20014, 20015, 20016, 20017, 20018, 20019, 20020};
private int[] defaultFeaturedIds = new int[] {23002, 1003, 1101, 1104, 23000, 23003};
-
+
private static int starglightId = 252;
private static int embersId = 251;
public GachaService(GameServer server) {
super(server);
this.gachaBanners = new Int2ObjectOpenHashMap<>();
-
+
try {
this.watch();
} catch (Exception e) {
@@ -65,15 +65,15 @@ public class GachaService extends BaseGameService {
public int getRandom(int[] array) {
return array[randomRange(0, array.length - 1)];
}
-
+
private String getBannerFileName() {
return LunarCore.getConfig().getDataDir() + "/Banners.json";
}
-
+
public void watch() throws Exception {
// Load banners first
this.loadBanners();
-
+
// Create watch service
this.watchService = FileSystems.getDefault().newWatchService();
Path watchPath = Paths.get(LunarCore.getConfig().getDataDir());
@@ -88,12 +88,12 @@ public class GachaService extends BaseGameService {
if (event.context() == null) {
continue;
}
-
+
if (event.context() instanceof Path path && path.toString().equals("Banners.json")) {
loadBanners();
}
}
-
+
key.reset();
}
} catch (Exception e) {
@@ -105,7 +105,7 @@ public class GachaService extends BaseGameService {
public synchronized void loadBanners() {
this.getGachaBanners().clear();
-
+
try (FileReader fileReader = new FileReader(getBannerFileName())) {
List<GachaBanner> banners = JsonUtils.loadToList(fileReader, GachaBanner.class);
for (GachaBanner banner : banners) {
@@ -119,7 +119,7 @@ public class GachaService extends BaseGameService {
public synchronized void doPulls(Player player, int gachaId, int times) {
// Sanity checks
if (times != 10 && times != 1) return;
-
+
// Prevent player from using gacha if they are at max light cones
if (player.getInventory().getTabByItemType(ItemMainType.Equipment).getSize() >= player.getInventory().getTabByItemType(ItemMainType.Equipment).getMaxCapacity()) {
player.sendPacket(new PacketDoGachaScRsp(Retcode.EQUIPMENT_EXCEED_LIMIT));
@@ -143,7 +143,7 @@ public class GachaService extends BaseGameService {
player.getInventory().removeItem(costItem, times);
}
-
+
// Add gacha ceiling
if (banner.getGachaType() == GachaType.Normal || banner.getGachaType() == GachaType.Newbie) {
player.getGachaInfo().addCeilingNum(times);
@@ -153,24 +153,33 @@ public class GachaService extends BaseGameService {
// Roll
PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(banner.getGachaType());
IntList wonItems = new IntArrayList(times);
+ var gachaSystem = LunarCore.getConfig().getGachaSystem();
+ GachaRiggedDice riggedDice = new GachaRiggedDice(gachaInfo, banner.getGachaType(), gachaSystem);
for (int i = 0; i < times; i++) {
- int random = this.randomRange(1, 10000);
int itemId = 0;
- int bonusYellowChance = gachaInfo.getPity5() >= 74 ? 100 * (gachaInfo.getPity5() - 73): 0;
- int yellowChance = 60 + (int) Math.floor(100f * (gachaInfo.getPity5() / 73f)) + bonusYellowChance;
- int purpleChance = 10000 - (510 + (int) Math.floor(790f * (gachaInfo.getPity4() / 8f)));
+ // Roll dice, see the file for implementation info.
+ // We do not need to adjust pity here since pity is adjusted automatically
+ // in the GachaRiggedDice class.
+ GachaRiggedDice.WonState wonState = riggedDice.roll();
- if (random <= yellowChance || gachaInfo.getPity5() >= 89) {
+ if (wonState == GachaRiggedDice.WonState.SuperRare) {
+ // Check rate-up
if (banner.getRateUpItems5().length > 0) {
int eventChance = this.randomRange(1, 100);
+ int bannerChance = 50;
+ if (banner.getGachaType() == GachaType.WeaponUp) {
+ bannerChance = 75;
+ }
- if (eventChance <= banner.getEventChance() || gachaInfo.getFailedFeaturedItemPulls() >= 1) {
+ if (eventChance <= bannerChance || gachaInfo.getFailedFeaturedItemPulls() >= 1) {
+ // Win/guarantee
itemId = getRandom(banner.getRateUpItems5());
+ // Reset
gachaInfo.setFailedFeaturedItemPulls(0);
} else {
- // Lost the 50/50... rip
+ // Lost the 50/50... point and laugh at this person
gachaInfo.addFailedFeaturedItemPulls(1);
}
}
@@ -183,15 +192,12 @@ public class GachaService extends BaseGameService {
itemId = getRandom(this.yellowWeapons);
}
}
-
- // Pity
- gachaInfo.addPity4(1);
- gachaInfo.setPity5(0);
- } else if (random >= purpleChance || gachaInfo.getPity4() >= 9) {
+ } else if (wonState == GachaRiggedDice.WonState.VeryRare) {
+ // Check banner rate-up
if (banner.getRateUpItems4().length > 0) {
int eventChance = this.randomRange(1, 100);
-
if (eventChance >= 50) {
+ // Win/guarantee
itemId = getRandom(banner.getRateUpItems4());
}
}
@@ -204,16 +210,8 @@ public class GachaService extends BaseGameService {
itemId = getRandom(this.purpleWeapons);
}
}
-
- // Pity
- gachaInfo.addPity5(1);
- gachaInfo.setPity4(0);
} else {
itemId = getRandom(this.blueWeapons);
-
- // Pity
- gachaInfo.addPity4(1);
- gachaInfo.addPity5(1);
}
// Add winning item
@@ -242,7 +240,7 @@ public class GachaService extends BaseGameService {
GameAvatar avatar = player.getAvatars().getAvatarById(avatarId);
if (avatar != null) {
int dupeLevel = avatar.getRank();
- int dupeItemId = avatar.getExcel().getRankUpItemId();
+ int dupeItemId = avatar.getExcel().getRankUpItemId();
GameItem dupeItem = player.getInventory().getMaterialByItemId(avatar.getExcel().getRankUpItemId());
if (dupeItem != null) {
dupeLevel += dupeItem.getCount();
@@ -250,13 +248,13 @@ public class GachaService extends BaseGameService {
if (dupeLevel < 6) {
// Not max const
- addStarglitter = 8;
+ addStarglitter = gachaSystem.getConsNew();
// Add 1 rank
gachaItem.getTransferItemList().addItemList(Item.newInstance().setItemId(dupeItemId).setNum(1));
player.getInventory().addItem(dupeItemId, 1);
} else {
// Is max rank
- addStarglitter = 20;
+ addStarglitter = gachaSystem.getConsMax();
}
if (itemData.getRarity() == ItemRarity.SuperRare) {
@@ -270,17 +268,16 @@ public class GachaService extends BaseGameService {
// Is weapon
switch (itemData.getRarity()) {
case SuperRare:
- addStarglitter = 40;
+ addStarglitter = gachaSystem.getConsWeapon5();
break;
case VeryRare:
- addStarglitter = 8;
+ addStarglitter = gachaSystem.getConsWeapon4();
break;
case Rare:
- addStardust = 20;
+ addStardust = gachaSystem.getConsWeapon3();
break;
default:
break;
}
}
// Create item
@@ -297,7 +294,7 @@ public class GachaService extends BaseGameService {
} if (addStarglitter > 0) {
gachaItem.getTokenItem().addItemList(Item.newInstance().setItemId(starglightId).setNum(addStarglitter));
}
-
+
// Add to gacha item list rsp
list.add(gachaItem);
}
@@ -312,32 +309,32 @@ public class GachaService extends BaseGameService {
// Packets
player.sendPacket(new PacketDoGachaScRsp(player, banner, times, list));
}
-
+
public List<GameItem> exchangeGachaCeiling(Player player, int avatarId) {
// Sanity check
if (player.getGachaInfo().getCeilingNum() < GameConstants.GACHA_CEILING_MAX || player.getGachaInfo().isCeilingClaimed()) {
return null;
}
-
+
// Make sure the player is getting a valid avatar
if (!Utils.arrayContains(this.getYellowAvatars(), avatarId)) {
return null;
}
-
+
// Add items
List<GameItem> items = new ArrayList<>();
-
+
if (player.getAvatars().hasAvatar(avatarId)) {
// Add eidolon if player already has the avatar
items.add(new GameItem(avatarId + 10000));
} else {
items.add(new GameItem(avatarId));
}
-
+
player.getInventory().addItems(items);
player.getGachaInfo().setCeilingClaimed(true);
player.save();
-
+
return items;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment