Commit e8371677 authored by AnimeGitB's avatar AnimeGitB Committed by Luke H-W
Browse files

Add gachaTimesLimit for beginner banner

Also add some more return codes
parent fe50a42a
package emu.grasscutter.game.gacha; package emu.grasscutter.game.gacha;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.game.Account;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo; import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo;
import emu.grasscutter.net.proto.GachaUpInfoOuterClass.GachaUpInfo; import emu.grasscutter.net.proto.GachaUpInfoOuterClass.GachaUpInfo;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import lombok.Getter;
import static emu.grasscutter.Configuration.*; import static emu.grasscutter.Configuration.*;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.common.ItemParamData;
public class GachaBanner { public class GachaBanner {
private int gachaType; @Getter private int gachaType;
private int scheduleId; @Getter private int scheduleId;
private String prefabPath; @Getter private String prefabPath;
private String previewPrefabPath; @Getter private String previewPrefabPath;
private String titlePath; @Getter private String titlePath;
private int costItemId = 0; private int costItemId = 0;
private int costItemAmount = 1; private int costItemAmount = 1;
private int costItemId10 = 0; private int costItemId10 = 0;
private int costItemAmount10 = 10; private int costItemAmount10 = 10;
private int beginTime; @Getter private int beginTime;
private int endTime; @Getter private int endTime;
private int sortId; @Getter private int sortId;
@Getter private int gachaTimesLimit = Integer.MAX_VALUE;
private int[] rateUpItems4 = {}; private int[] rateUpItems4 = {};
private int[] rateUpItems5 = {}; private int[] rateUpItems5 = {};
private int[] fallbackItems3 = {11301, 11302, 11306, 12301, 12302, 12305, 13303, 14301, 14302, 14304, 15301, 15302, 15304}; @Getter 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}; @Getter 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}; @Getter 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}; @Getter private int[] fallbackItems5Pool1 = {1003, 1016, 1042, 1035, 1041};
private int[] fallbackItems5Pool2 = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502}; @Getter private int[] fallbackItems5Pool2 = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502};
private boolean removeC6FromPool = false; @Getter private boolean removeC6FromPool = false;
private boolean autoStripRateUpFromFallback = true; @Getter private boolean autoStripRateUpFromFallback = true;
private int[][] weights4 = {{1,510}, {8,510}, {10,10000}}; private int[][] weights4 = {{1,510}, {8,510}, {10,10000}};
private int[][] weights5 = {{1,75}, {73,150}, {90,10000}}; private int[][] weights5 = {{1,75}, {73,150}, {90,10000}};
private int[][] poolBalanceWeights4 = {{1,255}, {17,255}, {21,10455}}; private int[][] poolBalanceWeights4 = {{1,255}, {17,255}, {21,10455}};
private int[][] poolBalanceWeights5 = {{1,30}, {147,150}, {181,10230}}; private int[][] poolBalanceWeights5 = {{1,30}, {147,150}, {181,10230}};
private int eventChance4 = 50; // Chance to win a featured event item private int eventChance4 = 50; // Chance to win a featured event item
private int eventChance5 = 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 // Kinda wanna deprecate these but they're in people's configs
private int[] rateUpItems1 = {}; private int[] rateUpItems1 = {};
private int[] rateUpItems2 = {}; private int[] rateUpItems2 = {};
private int eventChance = -1; private int eventChance = -1;
private int costItem = 0; private int costItem = 0;
private int wishMaxProgress = 2; @Getter 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;
}
public ItemParamData getCost(int numRolls) { public ItemParamData getCost(int numRolls) {
return switch (numRolls) { return switch (numRolls) {
...@@ -84,18 +58,6 @@ public class GachaBanner { ...@@ -84,18 +58,6 @@ public class GachaBanner {
return (costItem > 0) ? costItem : costItemId; return (costItem > 0) ? costItem : costItemId;
} }
public int getBeginTime() {
return beginTime;
}
public int getEndTime() {
return endTime;
}
public int getSortId() {
return sortId;
}
public int[] getRateUpItems4() { public int[] getRateUpItems4() {
return (rateUpItems2.length > 0) ? rateUpItems2 : rateUpItems4; return (rateUpItems2.length > 0) ? rateUpItems2 : rateUpItems4;
} }
...@@ -103,17 +65,6 @@ public class GachaBanner { ...@@ -103,17 +65,6 @@ public class GachaBanner {
return (rateUpItems1.length > 0) ? rateUpItems1 : rateUpItems5; 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() { public boolean hasEpitomized() {
return bannerType.equals(BannerType.WEAPON); return bannerType.equals(BannerType.WEAPON);
} }
...@@ -155,6 +106,11 @@ public class GachaBanner { ...@@ -155,6 +106,11 @@ public class GachaBanner {
// Grasscutter.getLogger().info("record = " + record); // Grasscutter.getLogger().info("record = " + record);
ItemParamData costItem1 = this.getCost(1); ItemParamData costItem1 = this.getCost(1);
ItemParamData costItem10 = this.getCost(10); 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() GachaInfo.Builder info = GachaInfo.newBuilder()
.setGachaType(this.getGachaType()) .setGachaType(this.getGachaType())
.setScheduleId(this.getScheduleId()) .setScheduleId(this.getScheduleId())
...@@ -170,13 +126,11 @@ public class GachaBanner { ...@@ -170,13 +126,11 @@ public class GachaBanner {
.setGachaProbUrlOversea(details) .setGachaProbUrlOversea(details)
.setGachaRecordUrl(record) .setGachaRecordUrl(record)
.setGachaRecordUrlOversea(record) .setGachaRecordUrlOversea(record)
.setLeftGachaTimes(Integer.MAX_VALUE) .setLeftGachaTimes(leftGachaTimes)
.setGachaTimesLimit(Integer.MAX_VALUE) .setGachaTimesLimit(gachaTimesLimit)
.setGachaSortId(this.getSortId()); .setGachaSortId(this.getSortId());
if(hasEpitomized()) { if(hasEpitomized()) {
PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(this);
info.setWishItemId(gachaInfo.getWishItemId()) info.setWishItemId(gachaInfo.getWishItemId())
.setWishProgress(gachaInfo.getFailedChosenItemPulls()) .setWishProgress(gachaInfo.getFailedChosenItemPulls())
.setWishMaxProgress(this.getWishMaxProgress()); .setWishMaxProgress(this.getWishMaxProgress());
......
...@@ -113,7 +113,7 @@ public class GachaManager { ...@@ -113,7 +113,7 @@ public class GachaManager {
fallbackItems5Pool1 = banner.getFallbackItems5Pool1(); fallbackItems5Pool1 = banner.getFallbackItems5Pool1();
fallbackItems5Pool2 = banner.getFallbackItems5Pool2(); fallbackItems5Pool2 = banner.getFallbackItems5Pool2();
if (banner.getAutoStripRateUpFromFallback()) { if (banner.isAutoStripRateUpFromFallback()) {
fallbackItems4Pool1 = Utils.setSubtract(fallbackItems4Pool1, rateUpItems4); fallbackItems4Pool1 = Utils.setSubtract(fallbackItems4Pool1, rateUpItems4);
fallbackItems4Pool2 = Utils.setSubtract(fallbackItems4Pool2, rateUpItems4); fallbackItems4Pool2 = Utils.setSubtract(fallbackItems4Pool2, rateUpItems4);
fallbackItems5Pool1 = Utils.setSubtract(fallbackItems5Pool1, rateUpItems5); fallbackItems5Pool1 = Utils.setSubtract(fallbackItems5Pool1, rateUpItems5);
...@@ -260,6 +260,7 @@ public class GachaManager { ...@@ -260,6 +260,7 @@ public class GachaManager {
public synchronized void doPulls(Player player, int scheduleId, int times) { public synchronized void doPulls(Player player, int scheduleId, int times) {
// Sanity check // Sanity check
if (times != 10 && times != 1) { if (times != 10 && times != 1) {
player.sendPacket(new PacketDoGachaRsp(Retcode.RET_GACHA_INVALID_TIMES));
return; return;
} }
Inventory inventory = player.getInventory(); Inventory inventory = player.getInventory();
...@@ -275,20 +276,28 @@ public class GachaManager { ...@@ -275,20 +276,28 @@ public class GachaManager {
return; 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 // Spend currency
ItemParamData cost = banner.getCost(times); ItemParamData cost = banner.getCost(times);
if (cost.getCount() > 0 && !inventory.payItem(cost)) { if (cost.getCount() > 0 && !inventory.payItem(cost)) {
player.sendPacket(new PacketDoGachaRsp()); player.sendPacket(new PacketDoGachaRsp(Retcode.RET_GACHA_COST_ITEM_NOT_ENOUGH));
return; return;
} }
// Add to character // Add to character
PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(banner); gachaInfo.addTotalPulls(times);
BannerPools pools = new BannerPools(banner); BannerPools pools = new BannerPools(banner);
List<GachaItem> list = new ArrayList<>(); List<GachaItem> list = new ArrayList<>();
int stardust = 0, starglitter = 0; 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.rateUpItems4 = removeC6FromPool(pools.rateUpItems4, player);
pools.rateUpItems5 = removeC6FromPool(pools.rateUpItems5, player); pools.rateUpItems5 = removeC6FromPool(pools.rateUpItems5, player);
pools.fallbackItems4Pool1 = removeC6FromPool(pools.fallbackItems4Pool1, player); pools.fallbackItems4Pool1 = removeC6FromPool(pools.fallbackItems4Pool1, player);
...@@ -331,7 +340,7 @@ public class GachaManager { ...@@ -331,7 +340,7 @@ public class GachaManager {
if (constellation >= 6) { // C6, give consolation starglitter if (constellation >= 6) { // C6, give consolation starglitter
addStarglitter = (itemData.getRankLevel()==5)? 25 : 5; addStarglitter = (itemData.getRankLevel()==5)? 25 : 5;
} else { // C0-C5, give constellation item } 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}); pools.removeFromAllPools(new int[] {itemId});
} }
addStarglitter = (itemData.getRankLevel()==5)? 10 : 2; addStarglitter = (itemData.getRankLevel()==5)? 10 : 2;
......
package emu.grasscutter.game.gacha; package emu.grasscutter.game.gacha;
import dev.morphia.annotations.Entity; import dev.morphia.annotations.Entity;
import lombok.Getter;
import lombok.Setter;
@Entity @Entity
public class PlayerGachaBannerInfo { public class PlayerGachaBannerInfo {
private int pity5 = 0; @Getter @Setter private int totalPulls = 0;
private int pity4 = 0; @Getter @Setter private int pity5 = 0;
@Getter @Setter private int pity4 = 0;
private int failedFeaturedItemPulls = 0; private int failedFeaturedItemPulls = 0;
private int failedFeatured4ItemPulls = 0; private int failedFeatured4ItemPulls = 0;
private int pity5Pool1 = 0; private int pity5Pool1 = 0;
...@@ -13,49 +16,21 @@ public class PlayerGachaBannerInfo { ...@@ -13,49 +16,21 @@ public class PlayerGachaBannerInfo {
private int pity4Pool1 = 0; private int pity4Pool1 = 0;
private int pity4Pool2 = 0; private int pity4Pool2 = 0;
private int failedChosenItemPulls = 0; @Getter @Setter private int failedChosenItemPulls = 0;
private int wishItemId = 0; @Getter @Setter private int wishItemId = 0;
public int getPity5() { public void addTotalPulls(int amount) {
return pity5; this.totalPulls += amount;
}
public void setPity5(int pity5) {
this.pity5 = pity5;
} }
public void addPity5(int amount) { public void addPity5(int amount) {
this.pity5 += amount; this.pity5 += amount;
} }
public int getPity4() {
return pity4;
}
public void setPity4(int pity4) {
this.pity4 = pity4;
}
public void addPity4(int amount) { public void addPity4(int amount) {
this.pity4 += 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) { public void addFailedChosenItemPulls(int amount) {
failedChosenItemPulls += amount; failedChosenItemPulls += amount;
} }
......
...@@ -19,12 +19,18 @@ public class PacketDoGachaRsp extends BasePacket { ...@@ -19,12 +19,18 @@ public class PacketDoGachaRsp extends BasePacket {
ItemParamData costItem = banner.getCost(1); ItemParamData costItem = banner.getCost(1);
ItemParamData costItem10 = banner.getCost(10); 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() DoGachaRsp.Builder rsp = DoGachaRsp.newBuilder()
.setGachaType(banner.getGachaType()) .setGachaType(banner.getGachaType())
.setGachaScheduleId(banner.getScheduleId()) .setGachaScheduleId(banner.getScheduleId())
.setGachaTimes(list.size()) .setGachaTimes(list.size())
.setNewGachaRandom(12345) .setNewGachaRandom(12345)
.setLeftGachaTimes(Integer.MAX_VALUE) .setLeftGachaTimes(leftGachaTimes)
.setGachaTimesLimit(gachaTimesLimit)
.setCostItemId(costItem.getId()) .setCostItemId(costItem.getId())
.setCostItemNum(costItem.getCount()) .setCostItemNum(costItem.getCount())
.setTenCostItemId(costItem10.getId()) .setTenCostItemId(costItem10.getId())
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment