From e8371677bdcb6477b1c2fd58b7a86feb78ac4731 Mon Sep 17 00:00:00 2001 From: AnimeGitB Date: Mon, 4 Jul 2022 01:27:50 +0930 Subject: [PATCH] Add gachaTimesLimit for beginner banner Also add some more return codes --- .../grasscutter/game/gacha/GachaBanner.java | 100 +++++------------- .../grasscutter/game/gacha/GachaManager.java | 19 +++- .../game/gacha/PlayerGachaBannerInfo.java | 49 +++------ .../server/packet/send/PacketDoGachaRsp.java | 8 +- 4 files changed, 60 insertions(+), 116 deletions(-) diff --git a/src/main/java/emu/grasscutter/game/gacha/GachaBanner.java b/src/main/java/emu/grasscutter/game/gacha/GachaBanner.java index 9286c23eb..dd68ad4af 100644 --- a/src/main/java/emu/grasscutter/game/gacha/GachaBanner.java +++ b/src/main/java/emu/grasscutter/game/gacha/GachaBanner.java @@ -1,77 +1,51 @@ package emu.grasscutter.game.gacha; -import emu.grasscutter.database.DatabaseHelper; -import emu.grasscutter.game.Account; +import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.game.player.Player; import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo; import emu.grasscutter.net.proto.GachaUpInfoOuterClass.GachaUpInfo; import emu.grasscutter.utils.Utils; +import lombok.Getter; import static emu.grasscutter.Configuration.*; -import emu.grasscutter.Grasscutter; -import emu.grasscutter.data.common.ItemParamData; - public class GachaBanner { - private int gachaType; - private int scheduleId; - private String prefabPath; - private String previewPrefabPath; - private String titlePath; + @Getter private int gachaType; + @Getter private int scheduleId; + @Getter private String prefabPath; + @Getter private String previewPrefabPath; + @Getter private String titlePath; private int costItemId = 0; private int costItemAmount = 1; private int costItemId10 = 0; private int costItemAmount10 = 10; - private int beginTime; - private int endTime; - private int sortId; + @Getter private int beginTime; + @Getter private int endTime; + @Getter private int sortId; + @Getter private int gachaTimesLimit = Integer.MAX_VALUE; private int[] rateUpItems4 = {}; private int[] rateUpItems5 = {}; - private int[] fallbackItems3 = {11301, 11302, 11306, 12301, 12302, 12305, 13303, 14301, 14302, 14304, 15301, 15302, 15304}; - private int[] fallbackItems4Pool1 = {1014, 1020, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1064}; - private int[] fallbackItems4Pool2 = {11401, 11402, 11403, 11405, 12401, 12402, 12403, 12405, 13401, 13407, 14401, 14402, 14403, 14409, 15401, 15402, 15403, 15405}; - private int[] fallbackItems5Pool1 = {1003, 1016, 1042, 1035, 1041}; - private int[] fallbackItems5Pool2 = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502}; - private boolean removeC6FromPool = false; - private boolean autoStripRateUpFromFallback = true; + @Getter private int[] fallbackItems3 = {11301, 11302, 11306, 12301, 12302, 12305, 13303, 14301, 14302, 14304, 15301, 15302, 15304}; + @Getter private int[] fallbackItems4Pool1 = {1014, 1020, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1064}; + @Getter private int[] fallbackItems4Pool2 = {11401, 11402, 11403, 11405, 12401, 12402, 12403, 12405, 13401, 13407, 14401, 14402, 14403, 14409, 15401, 15402, 15403, 15405}; + @Getter private int[] fallbackItems5Pool1 = {1003, 1016, 1042, 1035, 1041}; + @Getter private int[] fallbackItems5Pool2 = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502}; + @Getter private boolean removeC6FromPool = false; + @Getter private boolean autoStripRateUpFromFallback = true; private int[][] weights4 = {{1,510}, {8,510}, {10,10000}}; private int[][] weights5 = {{1,75}, {73,150}, {90,10000}}; private int[][] poolBalanceWeights4 = {{1,255}, {17,255}, {21,10455}}; private int[][] poolBalanceWeights5 = {{1,30}, {147,150}, {181,10230}}; private int eventChance4 = 50; // Chance to win a featured event item private int eventChance5 = 50; // Chance to win a featured event item - private BannerType bannerType = BannerType.STANDARD; + @Getter private BannerType bannerType = BannerType.STANDARD; // Kinda wanna deprecate these but they're in people's configs private int[] rateUpItems1 = {}; private int[] rateUpItems2 = {}; private int eventChance = -1; private int costItem = 0; - private int wishMaxProgress = 2; - - public int getGachaType() { - return gachaType; - } - - public BannerType getBannerType() { - return bannerType; - } - - public int getScheduleId() { - return scheduleId; - } - - public String getPrefabPath() { - return prefabPath; - } - - public String getPreviewPrefabPath() { - return previewPrefabPath; - } - - public String getTitlePath() { - return titlePath; - } + @Getter private int wishMaxProgress = 2; public ItemParamData getCost(int numRolls) { return switch (numRolls) { @@ -84,18 +58,6 @@ public class GachaBanner { return (costItem > 0) ? costItem : costItemId; } - public int getBeginTime() { - return beginTime; - } - - public int getEndTime() { - return endTime; - } - - public int getSortId() { - return sortId; - } - public int[] getRateUpItems4() { return (rateUpItems2.length > 0) ? rateUpItems2 : rateUpItems4; } @@ -103,17 +65,6 @@ public class GachaBanner { return (rateUpItems1.length > 0) ? rateUpItems1 : rateUpItems5; } - public int[] getFallbackItems3() {return fallbackItems3;} - public int[] getFallbackItems4Pool1() {return fallbackItems4Pool1;} - public int[] getFallbackItems4Pool2() {return fallbackItems4Pool2;} - public int[] getFallbackItems5Pool1() {return fallbackItems5Pool1;} - public int[] getFallbackItems5Pool2() {return fallbackItems5Pool2;} - - public boolean getRemoveC6FromPool() {return removeC6FromPool;} - public boolean getAutoStripRateUpFromFallback() {return autoStripRateUpFromFallback;} - - public int getWishMaxProgress() {return wishMaxProgress;} - public boolean hasEpitomized() { return bannerType.equals(BannerType.WEAPON); } @@ -155,6 +106,11 @@ public class GachaBanner { // Grasscutter.getLogger().info("record = " + record); ItemParamData costItem1 = this.getCost(1); ItemParamData costItem10 = this.getCost(10); + PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(this); + int leftGachaTimes = switch(gachaTimesLimit) { + case Integer.MAX_VALUE -> Integer.MAX_VALUE; + default -> Math.max(gachaTimesLimit - gachaInfo.getTotalPulls(), 0); + }; GachaInfo.Builder info = GachaInfo.newBuilder() .setGachaType(this.getGachaType()) .setScheduleId(this.getScheduleId()) @@ -170,13 +126,11 @@ public class GachaBanner { .setGachaProbUrlOversea(details) .setGachaRecordUrl(record) .setGachaRecordUrlOversea(record) - .setLeftGachaTimes(Integer.MAX_VALUE) - .setGachaTimesLimit(Integer.MAX_VALUE) + .setLeftGachaTimes(leftGachaTimes) + .setGachaTimesLimit(gachaTimesLimit) .setGachaSortId(this.getSortId()); if(hasEpitomized()) { - PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(this); - info.setWishItemId(gachaInfo.getWishItemId()) .setWishProgress(gachaInfo.getFailedChosenItemPulls()) .setWishMaxProgress(this.getWishMaxProgress()); diff --git a/src/main/java/emu/grasscutter/game/gacha/GachaManager.java b/src/main/java/emu/grasscutter/game/gacha/GachaManager.java index b91d09a3a..661bfca5e 100644 --- a/src/main/java/emu/grasscutter/game/gacha/GachaManager.java +++ b/src/main/java/emu/grasscutter/game/gacha/GachaManager.java @@ -113,7 +113,7 @@ public class GachaManager { fallbackItems5Pool1 = banner.getFallbackItems5Pool1(); fallbackItems5Pool2 = banner.getFallbackItems5Pool2(); - if (banner.getAutoStripRateUpFromFallback()) { + if (banner.isAutoStripRateUpFromFallback()) { fallbackItems4Pool1 = Utils.setSubtract(fallbackItems4Pool1, rateUpItems4); fallbackItems4Pool2 = Utils.setSubtract(fallbackItems4Pool2, rateUpItems4); fallbackItems5Pool1 = Utils.setSubtract(fallbackItems5Pool1, rateUpItems5); @@ -260,6 +260,7 @@ public class GachaManager { public synchronized void doPulls(Player player, int scheduleId, int times) { // Sanity check if (times != 10 && times != 1) { + player.sendPacket(new PacketDoGachaRsp(Retcode.RET_GACHA_INVALID_TIMES)); return; } Inventory inventory = player.getInventory(); @@ -275,20 +276,28 @@ public class GachaManager { return; } + // Check against total limit + PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(banner); + int gachaTimesLimit = banner.getGachaTimesLimit(); + if (gachaTimesLimit != Integer.MAX_VALUE && (gachaInfo.getTotalPulls() + times) > gachaTimesLimit) { + player.sendPacket(new PacketDoGachaRsp(Retcode.RET_GACHA_TIMES_LIMIT)); + return; + } + // Spend currency ItemParamData cost = banner.getCost(times); if (cost.getCount() > 0 && !inventory.payItem(cost)) { - player.sendPacket(new PacketDoGachaRsp()); + player.sendPacket(new PacketDoGachaRsp(Retcode.RET_GACHA_COST_ITEM_NOT_ENOUGH)); return; } // Add to character - PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(banner); + gachaInfo.addTotalPulls(times); BannerPools pools = new BannerPools(banner); List list = new ArrayList<>(); int stardust = 0, starglitter = 0; - if (banner.getRemoveC6FromPool()) { // The ultimate form of pity (non-vanilla) + if (banner.isRemoveC6FromPool()) { // The ultimate form of pity (non-vanilla) pools.rateUpItems4 = removeC6FromPool(pools.rateUpItems4, player); pools.rateUpItems5 = removeC6FromPool(pools.rateUpItems5, player); pools.fallbackItems4Pool1 = removeC6FromPool(pools.fallbackItems4Pool1, player); @@ -331,7 +340,7 @@ public class GachaManager { if (constellation >= 6) { // C6, give consolation starglitter addStarglitter = (itemData.getRankLevel()==5)? 25 : 5; } else { // C0-C5, give constellation item - if (banner.getRemoveC6FromPool() && constellation == 5) { // New C6, remove it from the pools so we don't get C7 in a 10pull + if (banner.isRemoveC6FromPool() && constellation == 5) { // New C6, remove it from the pools so we don't get C7 in a 10pull pools.removeFromAllPools(new int[] {itemId}); } addStarglitter = (itemData.getRankLevel()==5)? 10 : 2; diff --git a/src/main/java/emu/grasscutter/game/gacha/PlayerGachaBannerInfo.java b/src/main/java/emu/grasscutter/game/gacha/PlayerGachaBannerInfo.java index 00b07ed96..baac57744 100644 --- a/src/main/java/emu/grasscutter/game/gacha/PlayerGachaBannerInfo.java +++ b/src/main/java/emu/grasscutter/game/gacha/PlayerGachaBannerInfo.java @@ -1,11 +1,14 @@ package emu.grasscutter.game.gacha; import dev.morphia.annotations.Entity; +import lombok.Getter; +import lombok.Setter; @Entity public class PlayerGachaBannerInfo { - private int pity5 = 0; - private int pity4 = 0; + @Getter @Setter private int totalPulls = 0; + @Getter @Setter private int pity5 = 0; + @Getter @Setter private int pity4 = 0; private int failedFeaturedItemPulls = 0; private int failedFeatured4ItemPulls = 0; private int pity5Pool1 = 0; @@ -13,49 +16,21 @@ public class PlayerGachaBannerInfo { private int pity4Pool1 = 0; private int pity4Pool2 = 0; - private int failedChosenItemPulls = 0; - private int wishItemId = 0; - - public int getPity5() { - return pity5; + @Getter @Setter private int failedChosenItemPulls = 0; + @Getter @Setter private int wishItemId = 0; + + public void addTotalPulls(int amount) { + this.totalPulls += amount; } - - public void setPity5(int pity5) { - this.pity5 = pity5; - } - + public void addPity5(int amount) { this.pity5 += amount; } - - public int getPity4() { - return pity4; - } - - public void setPity4(int pity4) { - this.pity4 = pity4; - } - + public void addPity4(int amount) { this.pity4 += amount; } - public int getWishItemId() { - return wishItemId; - } - - public void setWishItemId(int wishItemId) { - this.wishItemId = wishItemId; - } - - public int getFailedChosenItemPulls() { - return failedChosenItemPulls; - } - - public void setFailedChosenItemPulls(int amount) { - failedChosenItemPulls = amount; - } - public void addFailedChosenItemPulls(int amount) { failedChosenItemPulls += amount; } diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketDoGachaRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketDoGachaRsp.java index f63e053b6..c7f8fc6ec 100644 --- a/src/main/java/emu/grasscutter/server/packet/send/PacketDoGachaRsp.java +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketDoGachaRsp.java @@ -19,12 +19,18 @@ public class PacketDoGachaRsp extends BasePacket { ItemParamData costItem = banner.getCost(1); ItemParamData costItem10 = banner.getCost(10); + int gachaTimesLimit = banner.getGachaTimesLimit(); + int leftGachaTimes = switch(gachaTimesLimit) { + case Integer.MAX_VALUE -> Integer.MAX_VALUE; + default -> Math.max(gachaTimesLimit - gachaInfo.getTotalPulls(), 0); + }; DoGachaRsp.Builder rsp = DoGachaRsp.newBuilder() .setGachaType(banner.getGachaType()) .setGachaScheduleId(banner.getScheduleId()) .setGachaTimes(list.size()) .setNewGachaRandom(12345) - .setLeftGachaTimes(Integer.MAX_VALUE) + .setLeftGachaTimes(leftGachaTimes) + .setGachaTimesLimit(gachaTimesLimit) .setCostItemId(costItem.getId()) .setCostItemNum(costItem.getCount()) .setTenCostItemId(costItem10.getId())