GachaBanner.java 6.37 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
package emu.grasscutter.game.gacha;

3
import emu.grasscutter.data.common.ItemParamData;
CamChua_VN's avatar
CamChua_VN committed
4
import emu.grasscutter.game.player.Player;
Melledy's avatar
Melledy committed
5
6
import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo;
import emu.grasscutter.net.proto.GachaUpInfoOuterClass.GachaUpInfo;
AnimeGitB's avatar
AnimeGitB committed
7
import emu.grasscutter.utils.Utils;
8
import lombok.Getter;
Melledy's avatar
Melledy committed
9

10
11
import static emu.grasscutter.Configuration.*;

Melledy's avatar
Melledy committed
12
public class GachaBanner {
13
14
15
16
17
	@Getter private int gachaType;
	@Getter private int scheduleId;
	@Getter private String prefabPath;
	@Getter private String previewPrefabPath;
	@Getter private String titlePath;
18
19
20
21
	private int costItemId = 0;
	private int costItemAmount = 1;
	private int costItemId10 = 0;
	private int costItemAmount10 = 10;
22
23
24
25
	@Getter private int beginTime;
	@Getter private int endTime;
	@Getter private int sortId;
	@Getter private int gachaTimesLimit = Integer.MAX_VALUE;
AnimeGitB's avatar
AnimeGitB committed
26
27
	private int[] rateUpItems4 = {};
	private int[] rateUpItems5 = {};
28
29
30
31
32
33
34
	@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;
AnimeGitB's avatar
AnimeGitB committed
35
36
37
38
39
40
	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
41
	@Getter private BannerType bannerType = BannerType.STANDARD;
AnimeGitB's avatar
AnimeGitB committed
42
43
44
45
46

	// Kinda wanna deprecate these but they're in people's configs
	private int[] rateUpItems1 = {};
	private int[] rateUpItems2 = {};
	private int eventChance = -1;
47
	private int costItem = 0;
48
	@Getter private int wishMaxProgress = 2;
Melledy's avatar
Melledy committed
49

50
51
52
53
54
55
56
	public ItemParamData getCost(int numRolls) {
		return switch (numRolls) {
			case 10 -> new ItemParamData((costItemId10 > 0) ? costItemId10 : getCostItem(), costItemAmount10);
			default -> new ItemParamData(getCostItem(), costItemAmount * numRolls);
		};
	}

Melledy's avatar
Melledy committed
57
	public int getCostItem() {
58
		return (costItem > 0) ? costItem : costItemId;
Melledy's avatar
Melledy committed
59
60
	}

AnimeGitB's avatar
AnimeGitB committed
61
62
	public int[] getRateUpItems4() {
		return (rateUpItems2.length > 0) ? rateUpItems2 : rateUpItems4;
Melledy's avatar
Melledy committed
63
	}
AnimeGitB's avatar
AnimeGitB committed
64
65
	public int[] getRateUpItems5() {
		return (rateUpItems1.length > 0) ? rateUpItems1 : rateUpItems5;
Melledy's avatar
Melledy committed
66
67
	}

CamChua_VN's avatar
CamChua_VN committed
68
69
70
	public boolean hasEpitomized() {
		return bannerType.equals(BannerType.WEAPON);
	}
AnimeGitB's avatar
AnimeGitB committed
71
72
73
74
75
76

	public int getWeight(int rarity, int pity) {
		return switch(rarity) {
			case 4 -> Utils.lerp(pity, weights4);
			default -> Utils.lerp(pity, weights5);
		};
Melledy's avatar
Melledy committed
77
78
	}

AnimeGitB's avatar
AnimeGitB committed
79
80
81
82
83
	public int getPoolBalanceWeight(int rarity, int pity) {
		return switch(rarity) {
			case 4 -> Utils.lerp(pity, poolBalanceWeights4);
			default -> Utils.lerp(pity, poolBalanceWeights5);
		};
Melledy's avatar
Melledy committed
84
85
	}

AnimeGitB's avatar
AnimeGitB committed
86
87
88
89
90
	public int getEventChance(int rarity) {
		return switch(rarity) {
			case 4 -> eventChance4;
			default -> (eventChance > -1) ? eventChance : eventChance5;
		};
Melledy's avatar
Melledy committed
91
	}
92
	
93
94
95
96
	public GachaInfo toProto(Player player) {
		// TODO: use other Nonce/key insteadof session key to ensure the overall security for the player
		String sessionKey = player.getAccount().getSessionKey();
		
97
98
99
		String record = "http" + (HTTP_ENCRYPTION.useInRouting ? "s" : "") + "://"
						+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress) + ":"
						+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
100
						+ "/gacha?s=" + sessionKey + "&gachaType=" + gachaType;
KingRainbow44's avatar
KingRainbow44 committed
101
102
103
		String details = "http" + (HTTP_ENCRYPTION.useInRouting ? "s" : "") + "://"
						+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress) + ":"
						+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
104
						+ "/gacha/details?s=" + sessionKey + "&scheduleId=" + scheduleId;
ImmuState's avatar
ImmuState committed
105

106
		// Grasscutter.getLogger().info("record = " + record);
107
108
		ItemParamData costItem1 = this.getCost(1);
		ItemParamData costItem10 = this.getCost(10);
109
110
111
112
113
		PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(this);
		int leftGachaTimes = switch(gachaTimesLimit) {
			case Integer.MAX_VALUE -> Integer.MAX_VALUE;
			default -> Math.max(gachaTimesLimit - gachaInfo.getTotalPulls(), 0);
		};
Melledy's avatar
Melledy committed
114
115
116
117
118
		GachaInfo.Builder info = GachaInfo.newBuilder()
				.setGachaType(this.getGachaType())
				.setScheduleId(this.getScheduleId())
				.setBeginTime(this.getBeginTime())
				.setEndTime(this.getEndTime())
119
120
121
122
				.setCostItemId(costItem1.getId())
	            .setCostItemNum(costItem1.getCount())
	            .setTenCostItemId(costItem10.getId())
	            .setTenCostItemNum(costItem10.getCount())
Melledy's avatar
Melledy committed
123
124
	            .setGachaPrefabPath(this.getPrefabPath())
	            .setGachaPreviewPrefabPath(this.getPreviewPrefabPath())
ImmuState's avatar
ImmuState committed
125
126
	            .setGachaProbUrl(details)
	            .setGachaProbUrlOversea(details)
Melledy's avatar
Melledy committed
127
128
	            .setGachaRecordUrl(record)
	            .setGachaRecordUrlOversea(record)
129
130
	            .setLeftGachaTimes(leftGachaTimes)
	            .setGachaTimesLimit(gachaTimesLimit)
Melledy's avatar
Melledy committed
131
	            .setGachaSortId(this.getSortId());
CamChua_VN's avatar
CamChua_VN committed
132

133
		if(hasEpitomized()) {
CamChua_VN's avatar
CamChua_VN committed
134
135
136
137
138
			info.setWishItemId(gachaInfo.getWishItemId())
				.setWishProgress(gachaInfo.getFailedChosenItemPulls())
				.setWishMaxProgress(this.getWishMaxProgress());
		}

Melledy's avatar
Melledy committed
139
		if (this.getTitlePath() != null) {
140
			info.setTitleTextmap(this.getTitlePath());
Melledy's avatar
Melledy committed
141
142
		}
		
AnimeGitB's avatar
AnimeGitB committed
143
		if (this.getRateUpItems5().length > 0) {
Melledy's avatar
Melledy committed
144
145
			GachaUpInfo.Builder upInfo = GachaUpInfo.newBuilder().setItemParentType(1);
			
AnimeGitB's avatar
AnimeGitB committed
146
			for (int id : getRateUpItems5()) {
Melledy's avatar
Melledy committed
147
				upInfo.addItemIdList(id);
148
				info.addDisplayUp5ItemList(id);
Melledy's avatar
Melledy committed
149
150
151
152
153
			}
			
			info.addGachaUpInfoList(upInfo);
		}
		
AnimeGitB's avatar
AnimeGitB committed
154
		if (this.getRateUpItems4().length > 0) {
Melledy's avatar
Melledy committed
155
156
			GachaUpInfo.Builder upInfo = GachaUpInfo.newBuilder().setItemParentType(2);
			
AnimeGitB's avatar
AnimeGitB committed
157
			for (int id : getRateUpItems4()) {
Melledy's avatar
Melledy committed
158
				upInfo.addItemIdList(id);
159
160
				if (info.getDisplayUp4ItemListCount() == 0) {
					info.addDisplayUp4ItemList(id);
Melledy's avatar
Melledy committed
161
162
163
164
165
166
167
168
169
170
171
172
173
				}
			}
			
			info.addGachaUpInfoList(upInfo);
		}
		
		return info.build();
	}
	
	public enum BannerType {
		STANDARD, EVENT, WEAPON;
	}
}