mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-04 23:32:55 +08:00
Merge 0b8f9ad851
into d340758614
This commit is contained in:
commit
e1469e152d
@ -3,8 +3,7 @@ package emu.grasscutter;
|
|||||||
import emu.grasscutter.game.world.Position;
|
import emu.grasscutter.game.world.Position;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
import emu.grasscutter.utils.objects.SparseSet;
|
import emu.grasscutter.utils.objects.SparseSet;
|
||||||
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public final class GameConstants {
|
public final class GameConstants {
|
||||||
public static String VERSION = "4.0.0";
|
public static String VERSION = "4.0.0";
|
||||||
@ -60,4 +59,23 @@ public final class GameConstants {
|
|||||||
public static final int[] DEFAULT_ABILITY_HASHES =
|
public static final int[] DEFAULT_ABILITY_HASHES =
|
||||||
Arrays.stream(DEFAULT_ABILITY_STRINGS).mapToInt(Utils::abilityHash).toArray();
|
Arrays.stream(DEFAULT_ABILITY_STRINGS).mapToInt(Utils::abilityHash).toArray();
|
||||||
public static final int DEFAULT_ABILITY_NAME = Utils.abilityHash("Default");
|
public static final int DEFAULT_ABILITY_NAME = Utils.abilityHash("Default");
|
||||||
|
public static final Map<Integer, Integer> YAE_MIKO_ITEM_TO_REGION_COMBINE_BONUS = new HashMap<>() {{
|
||||||
|
put(104304, 1);
|
||||||
|
put(104307, 1);
|
||||||
|
put(104310, 2);
|
||||||
|
put(104313, 2);
|
||||||
|
put(104316, 2);
|
||||||
|
put(104320, 3);
|
||||||
|
put(104323, 3);
|
||||||
|
put(104326, 3);
|
||||||
|
put(104329, 4);
|
||||||
|
put(104332, 4);
|
||||||
|
put(104335, 4);
|
||||||
|
}};
|
||||||
|
public static final Map<Integer, List<Integer>> YAE_MIKO_REGION_TO_ITEM_COMBINE_BONUS = new HashMap<>() {{
|
||||||
|
put(1, List.of(104304, 104307));
|
||||||
|
put(2, List.of(104310, 104313, 104316));
|
||||||
|
put(3, List.of(104320, 104323, 104326));
|
||||||
|
put(4, List.of(104329, 104332, 104335));
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package emu.grasscutter.game.combine;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class CombineBonusData {
|
||||||
|
private int avatarId;
|
||||||
|
private int combineType;
|
||||||
|
private BonusType bonusType;
|
||||||
|
private List<Double> paramVec;
|
||||||
|
|
||||||
|
public enum BonusType {
|
||||||
|
COMBINE_BONUS_DOUBLE,
|
||||||
|
COMBINE_BONUS_REFUND,
|
||||||
|
COMBINE_BONUS_REFUND_RANDOM,
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
package emu.grasscutter.game.combine;
|
package emu.grasscutter.game.combine;
|
||||||
|
|
||||||
|
import emu.grasscutter.GameConstants;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.*;
|
import emu.grasscutter.data.*;
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
import emu.grasscutter.data.excels.CombineData;
|
import emu.grasscutter.data.excels.CombineData;
|
||||||
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.ActionReason;
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
@ -12,15 +14,26 @@ import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
|||||||
import emu.grasscutter.server.game.*;
|
import emu.grasscutter.server.game.*;
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
|
import io.netty.util.internal.ThreadLocalRandom;
|
||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class CombineManger extends BaseGameSystem {
|
public class CombineManger extends BaseGameSystem {
|
||||||
private static final Int2ObjectMap<List<Integer>> reliquaryDecomposeData =
|
private static final Int2ObjectMap<List<Integer>> reliquaryDecomposeData =
|
||||||
new Int2ObjectOpenHashMap<>();
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
private final Int2ObjectMap<CombineBonusData> combineBonusData = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
public CombineManger(GameServer server) {
|
public CombineManger(GameServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
|
|
||||||
|
// load combine bonus data
|
||||||
|
try {
|
||||||
|
DataLoader.loadList("CombineBonus.json", CombineBonusData.class)
|
||||||
|
.forEach(entry -> combineBonusData.put(entry.getAvatarId(), entry));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.error("Unable to load combine bonus data. Please place CombineBonus.json in the data folder.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
@ -47,7 +60,7 @@ public class CombineManger extends BaseGameSystem {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CombineResult combineItem(Player player, int cid, int count) {
|
public CombineResult combineItem(Player player, int cid, int count, long avatarGuid) {
|
||||||
// check config exist
|
// check config exist
|
||||||
if (!GameData.getCombineDataMap().containsKey(cid)) {
|
if (!GameData.getCombineDataMap().containsKey(cid)) {
|
||||||
player.getWorld().getHost().sendPacket(new PacketCombineRsp());
|
player.getWorld().getHost().sendPacket(new PacketCombineRsp());
|
||||||
@ -81,11 +94,104 @@ public class CombineManger extends BaseGameSystem {
|
|||||||
result.setMaterial(List.of());
|
result.setMaterial(List.of());
|
||||||
result.setResult(
|
result.setResult(
|
||||||
List.of(
|
List.of(
|
||||||
new ItemParamData(
|
new ItemParamData(combineData.getResultItemId(), combineData.getResultItemCount())));
|
||||||
combineData.getResultItemId(), combineData.getResultItemCount() * count)));
|
// lucky characters
|
||||||
// TODO lucky characters
|
int luckyCount = 0;
|
||||||
result.setExtra(List.of());
|
Avatar avatar = player.getAvatars().getAvatarByGuid(avatarGuid);
|
||||||
result.setBack(List.of());
|
CombineBonusData combineBonusAvatar = combineBonusData.get(avatar.getAvatarId());
|
||||||
|
if (combineBonusAvatar != null
|
||||||
|
&& combineData.getCombineType() == combineBonusAvatar.getCombineType()) {
|
||||||
|
double luckyChange = combineBonusAvatar.getParamVec().get(0);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (ThreadLocalRandom.current().nextDouble() <= luckyChange) {
|
||||||
|
luckyCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.setExtra(new ArrayList<ItemParamData>());
|
||||||
|
result.setBack(new ArrayList<ItemParamData>());
|
||||||
|
result.setRandom(new ArrayList<ItemParamData>());
|
||||||
|
|
||||||
|
// add lucky items
|
||||||
|
if (luckyCount > 0) {
|
||||||
|
switch (combineBonusAvatar.getBonusType()) {
|
||||||
|
case COMBINE_BONUS_DOUBLE -> {
|
||||||
|
var combineExtra = new ItemParamData(combineData.getResultItemId(), luckyCount);
|
||||||
|
player.getInventory().addItem(combineExtra);
|
||||||
|
result.getExtra().add(combineExtra);
|
||||||
|
}
|
||||||
|
case COMBINE_BONUS_REFUND -> {
|
||||||
|
if (combineData.getMaterialItems().size() == 1) {
|
||||||
|
var combineBack = new ItemParamData(combineData.getMaterialItems().get(0).getItemId(),
|
||||||
|
luckyCount);
|
||||||
|
player.getInventory().addItem(combineBack);
|
||||||
|
result.getBack().add(combineBack);
|
||||||
|
} else {
|
||||||
|
Map<Integer, Integer> mapIdCount = new HashMap<>();
|
||||||
|
for (int i = 0; i < luckyCount; i++) {
|
||||||
|
var randomId = combineData
|
||||||
|
.getMaterialItems()
|
||||||
|
.get(
|
||||||
|
ThreadLocalRandom.current()
|
||||||
|
.nextInt(combineData.getMaterialItems().size()))
|
||||||
|
.getItemId();
|
||||||
|
mapIdCount.put(randomId, mapIdCount.getOrDefault(randomId, 0) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entry : mapIdCount.entrySet()) {
|
||||||
|
var combineBack = new ItemParamData(entry.getKey(), entry.getValue());
|
||||||
|
player.getInventory().addItem(combineBack);
|
||||||
|
result.getBack().add(combineBack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case COMBINE_BONUS_REFUND_RANDOM -> {
|
||||||
|
// for yae miko, "Has a 25% chance to get 1 regional Character Talent Material
|
||||||
|
// (base
|
||||||
|
// material excluded) when crafting. The rarity is that of the base material."
|
||||||
|
// from wiki
|
||||||
|
// map of material id to region id
|
||||||
|
Map<Integer, Integer> itemToRegion = GameConstants.YAE_MIKO_ITEM_TO_REGION_COMBINE_BONUS;
|
||||||
|
|
||||||
|
// get list of material id with every region
|
||||||
|
Map<Integer, List<Integer>> regionToId = GameConstants.YAE_MIKO_REGION_TO_ITEM_COMBINE_BONUS;
|
||||||
|
|
||||||
|
// check material id in itemToRegion
|
||||||
|
int itemId = combineData.getMaterialItems().get(0).getItemId();
|
||||||
|
int rank = 0; // rank of material
|
||||||
|
if (itemToRegion.get(itemId) != null)
|
||||||
|
rank = 1;
|
||||||
|
if (itemToRegion.get(itemId - 1) != null) {
|
||||||
|
rank = 2;
|
||||||
|
itemId -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rank >= 1) { // if material is regional
|
||||||
|
// get list of material id with same region
|
||||||
|
List<Integer> listIdRandom = regionToId.get(itemToRegion.get(itemId));
|
||||||
|
// remove material id from array
|
||||||
|
listIdRandom.remove(Integer.valueOf(itemId));
|
||||||
|
|
||||||
|
HashMap<Integer, Integer> mapIdCount = new HashMap<>();
|
||||||
|
// pick random material from list with luckyCount
|
||||||
|
for (int i = 0; i < luckyCount; i++) {
|
||||||
|
int randomId = listIdRandom.get(ThreadLocalRandom.current().nextInt(listIdRandom.size()));
|
||||||
|
mapIdCount.put(randomId, mapIdCount.getOrDefault(randomId, 0) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to random list
|
||||||
|
for (var entry : mapIdCount.entrySet()) {
|
||||||
|
// if rank 2, add 1 to material id
|
||||||
|
var combineRandom = new ItemParamData(
|
||||||
|
(rank == 2) ? entry.getKey() + 1 : entry.getKey(), entry.getValue());
|
||||||
|
player.getInventory().addItem(combineRandom);
|
||||||
|
result.getRandom().add(combineRandom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2,42 +2,14 @@ package emu.grasscutter.game.combine;
|
|||||||
|
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter @Getter
|
||||||
public class CombineResult {
|
public class CombineResult {
|
||||||
private List<ItemParamData> material;
|
private List<ItemParamData> material;
|
||||||
private List<ItemParamData> result;
|
private List<ItemParamData> result;
|
||||||
private List<ItemParamData> extra;
|
private List<ItemParamData> extra;
|
||||||
private List<ItemParamData> back;
|
private List<ItemParamData> back;
|
||||||
|
private List<ItemParamData> random;
|
||||||
public List<ItemParamData> getMaterial() {
|
|
||||||
return material;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaterial(List<ItemParamData> material) {
|
|
||||||
this.material = material;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ItemParamData> getResult() {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResult(List<ItemParamData> result) {
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ItemParamData> getExtra() {
|
|
||||||
return extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExtra(List<ItemParamData> extra) {
|
|
||||||
this.extra = extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ItemParamData> getBack() {
|
|
||||||
return back;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBack(List<ItemParamData> back) {
|
|
||||||
this.back = back;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,11 @@ public class HandlerCombineReq extends PacketHandler {
|
|||||||
session
|
session
|
||||||
.getServer()
|
.getServer()
|
||||||
.getCombineSystem()
|
.getCombineSystem()
|
||||||
.combineItem(session.getPlayer(), req.getCombineId(), req.getCombineCount());
|
.combineItem(
|
||||||
|
session.getPlayer(),
|
||||||
|
req.getCombineId(),
|
||||||
|
req.getCombineCount(),
|
||||||
|
req.getAvatarGuid());
|
||||||
|
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
return;
|
return;
|
||||||
@ -33,7 +37,7 @@ public class HandlerCombineReq extends PacketHandler {
|
|||||||
toItemParamList(result.getResult()),
|
toItemParamList(result.getResult()),
|
||||||
toItemParamList(result.getExtra()),
|
toItemParamList(result.getExtra()),
|
||||||
toItemParamList(result.getBack()),
|
toItemParamList(result.getBack()),
|
||||||
toItemParamList(result.getBack())));
|
toItemParamList(result.getRandom())));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ItemParamOuterClass.ItemParam> toItemParamList(List<ItemParamData> list) {
|
private List<ItemParamOuterClass.ItemParam> toItemParamList(List<ItemParamData> list) {
|
||||||
|
Loading…
Reference in New Issue
Block a user