mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-25 08:22:53 +08:00
Merge pull request #124 from Yazawazi/development
Character fetter system
This commit is contained in:
commit
dac3cdbe17
@ -0,0 +1,48 @@
|
|||||||
|
package emu.grasscutter.command.commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import emu.grasscutter.command.Command;
|
||||||
|
import emu.grasscutter.command.CommandHandler;
|
||||||
|
import emu.grasscutter.data.GenshinData;
|
||||||
|
import emu.grasscutter.game.GenshinPlayer;
|
||||||
|
import emu.grasscutter.game.avatar.GenshinAvatar;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify;
|
||||||
|
|
||||||
|
@Command(label = "setfetterlevel", usage = "setfetterlevel <level>",
|
||||||
|
description = "Sets your fetter level for your current active character",
|
||||||
|
aliases = {"setfetterlvl"}, permission = "player.setfetterlevel")
|
||||||
|
public final class SetFetterLevelCommand implements CommandHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(GenshinPlayer sender, List<String> args) {
|
||||||
|
if (sender == null) {
|
||||||
|
CommandHandler.sendMessage(null, "Run this command in-game.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.size() < 1) {
|
||||||
|
CommandHandler.sendMessage(sender, "Usage: setfetterlevel <level>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
int fetterLevel = Integer.parseInt(args.get(0));
|
||||||
|
if (fetterLevel < 0 || fetterLevel > 10) {
|
||||||
|
CommandHandler.sendMessage(sender, "Fetter level must be between 0 and 10.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GenshinAvatar avatar = sender.getTeamManager().getCurrentAvatarEntity().getAvatar();
|
||||||
|
|
||||||
|
avatar.setFetterLevel(fetterLevel);
|
||||||
|
avatar.setFetterExp(GenshinData.getAvatarFetterLevelDataMap().get(fetterLevel).getExp());
|
||||||
|
avatar.save();
|
||||||
|
|
||||||
|
sender.sendPacket(new PacketAvatarFetterDataNotify(avatar));
|
||||||
|
CommandHandler.sendMessage(sender, "Fetter level set to " + fetterLevel);
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
CommandHandler.sendMessage(null, "Invalid fetter level.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,9 +24,36 @@ public class TelePortCommand implements CommandHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
float x = Float.parseFloat(args.get(0));
|
float x = 0f;
|
||||||
float y = Float.parseFloat(args.get(1));
|
float y = 0f;
|
||||||
float z = Float.parseFloat(args.get(2));
|
float z = 0f;
|
||||||
|
if (args.get(0).contains("~")) {
|
||||||
|
if (args.get(0).equals("~")) {
|
||||||
|
x = sender.getPos().getX();
|
||||||
|
} else {
|
||||||
|
x = Float.parseFloat(args.get(0).replace("~", "")) + sender.getPos().getX();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x = Float.parseFloat(args.get(0));
|
||||||
|
}
|
||||||
|
if (args.get(1).contains("~")) {
|
||||||
|
if (args.get(1).equals("~")) {
|
||||||
|
y = sender.getPos().getY();
|
||||||
|
} else {
|
||||||
|
y = Float.parseFloat(args.get(1).replace("~", "")) + sender.getPos().getY();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
y = Float.parseFloat(args.get(1));
|
||||||
|
}
|
||||||
|
if (args.get(2).contains("~")) {
|
||||||
|
if (args.get(2).equals("~")) {
|
||||||
|
z = sender.getPos().getZ();
|
||||||
|
} else {
|
||||||
|
z = Float.parseFloat(args.get(2).replace("~", "")) + sender.getPos().getZ();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
z = Float.parseFloat(args.get(2));
|
||||||
|
}
|
||||||
int sceneId = sender.getSceneId();
|
int sceneId = sender.getSceneId();
|
||||||
if (args.size() == 4){
|
if (args.size() == 4){
|
||||||
sceneId = Integer.parseInt(args.get(3));
|
sceneId = Integer.parseInt(args.get(3));
|
||||||
|
@ -31,6 +31,7 @@ public class GenshinData {
|
|||||||
private static final Int2ObjectMap<AvatarSkillDepotData> avatarSkillDepotDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<AvatarSkillDepotData> avatarSkillDepotDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<AvatarSkillData> avatarSkillDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<AvatarSkillData> avatarSkillDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<AvatarFetterLevelData> avatarFetterLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<AvatarPromoteData> avatarPromoteDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<AvatarPromoteData> avatarPromoteDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<ProudSkillData> proudSkillDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<ProudSkillData> proudSkillDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
@ -57,6 +58,8 @@ public class GenshinData {
|
|||||||
|
|
||||||
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<FetterData> fetterDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<FetterData> fetterDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||||
@ -114,6 +117,14 @@ public class GenshinData {
|
|||||||
return playerLevelDataMap;
|
return playerLevelDataMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<AvatarFetterLevelData> getAvatarFetterLevelDataMap() {
|
||||||
|
return avatarFetterLevelDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<FetterCharacterCardData> getFetterCharacterCardDataMap() {
|
||||||
|
return fetterCharacterCardDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
public static Int2ObjectMap<AvatarLevelData> getAvatarLevelDataMap() {
|
public static Int2ObjectMap<AvatarLevelData> getAvatarLevelDataMap() {
|
||||||
return avatarLevelDataMap;
|
return avatarLevelDataMap;
|
||||||
}
|
}
|
||||||
@ -175,6 +186,11 @@ public class GenshinData {
|
|||||||
AvatarLevelData levelData = avatarLevelDataMap.get(level);
|
AvatarLevelData levelData = avatarLevelDataMap.get(level);
|
||||||
return levelData != null ? levelData.getExp() : 0;
|
return levelData != null ? levelData.getExp() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getAvatarFetterLevelExpRequired(int level) {
|
||||||
|
AvatarFetterLevelData levelData = avatarFetterLevelDataMap.get(level);
|
||||||
|
return levelData != null ? levelData.getExp() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static Int2ObjectMap<ProudSkillData> getProudSkillDataMap() {
|
public static Int2ObjectMap<ProudSkillData> getProudSkillDataMap() {
|
||||||
return proudSkillDataMap;
|
return proudSkillDataMap;
|
||||||
@ -228,6 +244,10 @@ public class GenshinData {
|
|||||||
return sceneDataMap;
|
return sceneDataMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<RewardData> getRewardDataMap() {
|
||||||
|
return rewardDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
public static Map<Integer, List<Integer>> getFetterDataEntries() {
|
public static Map<Integer, List<Integer>> getFetterDataEntries() {
|
||||||
if (fetters.isEmpty()) {
|
if (fetters.isEmpty()) {
|
||||||
fetterDataMap.forEach((k, v) -> {
|
fetterDataMap.forEach((k, v) -> {
|
||||||
|
24
src/main/java/emu/grasscutter/data/common/OpenCondData.java
Normal file
24
src/main/java/emu/grasscutter/data/common/OpenCondData.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package emu.grasscutter.data.common;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OpenCondData {
|
||||||
|
private String CondType;
|
||||||
|
private List<Integer> ParamList;
|
||||||
|
|
||||||
|
public String getCondType() {
|
||||||
|
return CondType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCondType(String condType) {
|
||||||
|
CondType = condType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getParamList() {
|
||||||
|
return ParamList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParamList(List<Integer> paramList) {
|
||||||
|
ParamList = paramList;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package emu.grasscutter.data.common;
|
||||||
|
|
||||||
|
public class RewardItemData {
|
||||||
|
private int ItemId;
|
||||||
|
private int ItemCount;
|
||||||
|
|
||||||
|
public int getItemId() {
|
||||||
|
return ItemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemId(int itemId) {
|
||||||
|
ItemId = itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getItemCount() {
|
||||||
|
return ItemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemCount(int itemCount) {
|
||||||
|
ItemCount = itemCount;
|
||||||
|
}
|
||||||
|
}
|
@ -57,6 +57,8 @@ public class AvatarData extends GenshinResource {
|
|||||||
private IntList abilities;
|
private IntList abilities;
|
||||||
|
|
||||||
private List<Integer> fetters;
|
private List<Integer> fetters;
|
||||||
|
private int nameCardRewardId;
|
||||||
|
private int nameCardId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId(){
|
public int getId(){
|
||||||
@ -199,12 +201,28 @@ public class AvatarData extends GenshinResource {
|
|||||||
return fetters;
|
return fetters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getNameCardRewardId() {
|
||||||
|
return nameCardRewardId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNameCardId() {
|
||||||
|
return nameCardId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
this.skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(this.SkillDepotId);
|
this.skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(this.SkillDepotId);
|
||||||
|
|
||||||
// Get fetters from GenshinData
|
// Get fetters from GenshinData
|
||||||
this.fetters = GenshinData.getFetterDataEntries().get(this.Id);
|
this.fetters = GenshinData.getFetterDataEntries().get(this.Id);
|
||||||
|
|
||||||
|
if (GenshinData.getFetterCharacterCardDataMap().get(this.Id) != null) {
|
||||||
|
this.nameCardRewardId = GenshinData.getFetterCharacterCardDataMap().get(this.Id).getRewardId();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GenshinData.getRewardDataMap().get(this.nameCardRewardId) != null) {
|
||||||
|
this.nameCardId = GenshinData.getRewardDataMap().get(this.nameCardRewardId).getRewardItemList().get(0).getItemId();
|
||||||
|
}
|
||||||
|
|
||||||
int size = GenshinData.getAvatarCurveDataMap().size();
|
int size = GenshinData.getAvatarCurveDataMap().size();
|
||||||
this.hpGrowthCurve = new float[size];
|
this.hpGrowthCurve = new float[size];
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package emu.grasscutter.data.def;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GenshinResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
|
||||||
|
@ResourceType(name = "AvatarFettersLevelExcelConfigData.json")
|
||||||
|
public class AvatarFetterLevelData extends GenshinResource {
|
||||||
|
private int FetterLevel;
|
||||||
|
private int NeedExp;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return this.FetterLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel() {
|
||||||
|
return FetterLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExp() {
|
||||||
|
return NeedExp;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package emu.grasscutter.data.def;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GenshinResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||||
|
|
||||||
|
@ResourceType(name = "FetterCharacterCardExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
|
||||||
|
public class FetterCharacterCardData extends GenshinResource {
|
||||||
|
private int AvatarId;
|
||||||
|
private int RewardId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return AvatarId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRewardId() {
|
||||||
|
return RewardId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,17 @@
|
|||||||
package emu.grasscutter.data.def;
|
package emu.grasscutter.data.def;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import emu.grasscutter.data.GenshinResource;
|
import emu.grasscutter.data.GenshinResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||||
|
import emu.grasscutter.data.common.OpenCondData;
|
||||||
|
|
||||||
@ResourceType(name = {"FetterInfoExcelConfigData.json", "FettersExcelConfigData.json", "FetterStoryExcelConfigData.json"}, loadPriority = LoadPriority.HIGHEST)
|
@ResourceType(name = {"FetterInfoExcelConfigData.json", "FettersExcelConfigData.json", "FetterStoryExcelConfigData.json"}, loadPriority = LoadPriority.HIGHEST)
|
||||||
public class FetterData extends GenshinResource {
|
public class FetterData extends GenshinResource {
|
||||||
private int AvatarId;
|
private int AvatarId;
|
||||||
private int FetterId;
|
private int FetterId;
|
||||||
|
private List<OpenCondData> OpenCond;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public int getId() {
|
||||||
@ -18,6 +22,10 @@ public class FetterData extends GenshinResource {
|
|||||||
return AvatarId;
|
return AvatarId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<OpenCondData> getOpenConds() {
|
||||||
|
return OpenCond;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
}
|
}
|
||||||
|
27
src/main/java/emu/grasscutter/data/def/RewardData.java
Normal file
27
src/main/java/emu/grasscutter/data/def/RewardData.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package emu.grasscutter.data.def;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GenshinResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import emu.grasscutter.data.common.RewardItemData;
|
||||||
|
|
||||||
|
@ResourceType(name = "RewardExcelConfigData.json")
|
||||||
|
public class RewardData extends GenshinResource {
|
||||||
|
public int RewardId;
|
||||||
|
public List<RewardItemData> RewardItemList;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return RewardId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RewardItemData> getRewardItemList() {
|
||||||
|
return RewardItemList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -89,6 +89,12 @@ public class GenshinAvatar {
|
|||||||
private int flyCloak;
|
private int flyCloak;
|
||||||
private int costume;
|
private int costume;
|
||||||
private int bornTime;
|
private int bornTime;
|
||||||
|
|
||||||
|
private int fetterLevel = 1;
|
||||||
|
private int fetterExp;
|
||||||
|
|
||||||
|
private int nameCardRewardId;
|
||||||
|
private int nameCardId;
|
||||||
|
|
||||||
public GenshinAvatar() {
|
public GenshinAvatar() {
|
||||||
// Morhpia only!
|
// Morhpia only!
|
||||||
@ -107,6 +113,8 @@ public class GenshinAvatar {
|
|||||||
public GenshinAvatar(AvatarData data) {
|
public GenshinAvatar(AvatarData data) {
|
||||||
this();
|
this();
|
||||||
this.avatarId = data.getId();
|
this.avatarId = data.getId();
|
||||||
|
this.nameCardRewardId = data.getNameCardRewardId();
|
||||||
|
this.nameCardId = data.getNameCardId();
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.bornTime = (int) (System.currentTimeMillis() / 1000);
|
this.bornTime = (int) (System.currentTimeMillis() / 1000);
|
||||||
this.flyCloak = 140001;
|
this.flyCloak = 140001;
|
||||||
@ -169,6 +177,14 @@ public class GenshinAvatar {
|
|||||||
this.satiation = satiation;
|
this.satiation = satiation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getNameCardRewardId() {
|
||||||
|
return nameCardRewardId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNameCardRewardId(int nameCardRewardId) {
|
||||||
|
this.nameCardRewardId = nameCardRewardId;
|
||||||
|
}
|
||||||
|
|
||||||
public int getSatiationPenalty() {
|
public int getSatiationPenalty() {
|
||||||
return satiationPenalty;
|
return satiationPenalty;
|
||||||
}
|
}
|
||||||
@ -281,6 +297,30 @@ public class GenshinAvatar {
|
|||||||
return fetters;
|
return fetters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getFetterLevel() {
|
||||||
|
return fetterLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFetterLevel(int fetterLevel) {
|
||||||
|
this.fetterLevel = fetterLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFetterExp() {
|
||||||
|
return fetterExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFetterExp(int fetterExp) {
|
||||||
|
this.fetterExp = fetterExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNameCardId() {
|
||||||
|
return nameCardId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNameCardId(int nameCardId) {
|
||||||
|
this.nameCardId = nameCardId;
|
||||||
|
}
|
||||||
|
|
||||||
public float getCurrentHp() {
|
public float getCurrentHp() {
|
||||||
return currentHp;
|
return currentHp;
|
||||||
}
|
}
|
||||||
@ -403,6 +443,8 @@ public class GenshinAvatar {
|
|||||||
|
|
||||||
// Fetters
|
// Fetters
|
||||||
this.setFetterList(data.getFetters());
|
this.setFetterList(data.getFetters());
|
||||||
|
this.setNameCardRewardId(data.getNameCardRewardId());
|
||||||
|
this.setNameCardId(data.getNameCardId());
|
||||||
|
|
||||||
// Get hp percent, set to 100% if none
|
// Get hp percent, set to 100% if none
|
||||||
float hpPercent = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0 ? 1f : this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) / this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
float hpPercent = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0 ? 1f : this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) / this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
||||||
@ -702,8 +744,8 @@ public class GenshinAvatar {
|
|||||||
|
|
||||||
public AvatarInfo toProto() {
|
public AvatarInfo toProto() {
|
||||||
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder()
|
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder()
|
||||||
.setExpLevel(10)
|
.setExpLevel(this.getFetterLevel())
|
||||||
.setExpNumber(6325); // Highest Level
|
.setExpNumber(this.getFetterExp());
|
||||||
|
|
||||||
if (this.getFetterList() != null) {
|
if (this.getFetterList() != null) {
|
||||||
for (int i = 0; i < this.getFetterList().size(); i++) {
|
for (int i = 0; i < this.getFetterList().size(); i++) {
|
||||||
@ -715,6 +757,13 @@ public class GenshinAvatar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rewardId = this.getNameCardRewardId();
|
||||||
|
int cardId = this.getNameCardId();
|
||||||
|
|
||||||
|
if (this.getPlayer().getNameCardList().contains(cardId)) {
|
||||||
|
avatarFetter.addRewardedFetterLevelList(rewardId);
|
||||||
|
}
|
||||||
|
|
||||||
AvatarInfo.Builder avatarInfo = AvatarInfo.newBuilder()
|
AvatarInfo.Builder avatarInfo = AvatarInfo.newBuilder()
|
||||||
.setAvatarId(this.getAvatarId())
|
.setAvatarId(this.getAvatarId())
|
||||||
.setGuid(this.getGuid())
|
.setGuid(this.getGuid())
|
||||||
|
@ -711,6 +711,31 @@ public class InventoryManager {
|
|||||||
player.sendPacket(new PacketAvatarUpgradeRsp(avatar, oldLevel, oldPropMap));
|
player.sendPacket(new PacketAvatarUpgradeRsp(avatar, oldLevel, oldPropMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void upgradeAvatarFetterLevel(GenshinPlayer player, GenshinAvatar avatar, int expGain) {
|
||||||
|
// May work. Not test.
|
||||||
|
int maxLevel = 10; // Keep it until I think of a more "elegant" way
|
||||||
|
int level = avatar.getFetterLevel();
|
||||||
|
int exp = avatar.getFetterExp();
|
||||||
|
int reqExp = GenshinData.getAvatarFetterLevelExpRequired(level);
|
||||||
|
|
||||||
|
while (expGain > 0 && reqExp > 0 && level < maxLevel) {
|
||||||
|
int toGain = Math.min(expGain, reqExp - exp);
|
||||||
|
exp += toGain;
|
||||||
|
expGain -= toGain;
|
||||||
|
if (exp >= reqExp) {
|
||||||
|
exp = 0;
|
||||||
|
level += 1;
|
||||||
|
reqExp = GenshinData.getAvatarFetterLevelExpRequired(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
avatar.setFetterLevel(level);
|
||||||
|
avatar.setFetterExp(exp);
|
||||||
|
avatar.save();
|
||||||
|
|
||||||
|
player.sendPacket(new PacketAvatarPropNotify(avatar));
|
||||||
|
}
|
||||||
|
|
||||||
public void upgradeAvatarSkill(GenshinPlayer player, long guid, int skillId) {
|
public void upgradeAvatarSkill(GenshinPlayer player, long guid, int skillId) {
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
GenshinAvatar avatar = player.getAvatars().getAvatarByGuid(guid);
|
GenshinAvatar avatar = player.getAvatars().getAvatarByGuid(guid);
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GenshinData;
|
||||||
|
import emu.grasscutter.data.def.RewardData;
|
||||||
|
import emu.grasscutter.game.avatar.GenshinAvatar;
|
||||||
|
import emu.grasscutter.game.inventory.GenshinItem;
|
||||||
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq;
|
||||||
|
import emu.grasscutter.server.game.GameSession;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketAvatarFetterLevelRewardRsp;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketUnlockNameCardNotify;
|
||||||
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
|
|
||||||
|
@Opcodes(PacketOpcodes.AvatarFetterLevelRewardReq)
|
||||||
|
public class HandlerAvatarFetterLevelRewardReq extends PacketHandler {
|
||||||
|
@Override
|
||||||
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
|
AvatarFetterLevelRewardReq req = AvatarFetterLevelRewardReq.parseFrom(payload);
|
||||||
|
if (req.getFetterLevel() < 10) {
|
||||||
|
// You don't have a full level of fetter level, why do you want to get a divorce certificate?
|
||||||
|
session.send(new PacketAvatarFetterLevelRewardRsp(req.getAvatarGuid(), req.getFetterLevel()));
|
||||||
|
} else {
|
||||||
|
long avatarGuid = req.getAvatarGuid();
|
||||||
|
|
||||||
|
GenshinAvatar avatar = session
|
||||||
|
.getPlayer()
|
||||||
|
.getAvatars()
|
||||||
|
.getAvatarByGuid(avatarGuid);
|
||||||
|
|
||||||
|
int rewardId = avatar.getNameCardRewardId();
|
||||||
|
|
||||||
|
RewardData card = GenshinData.getRewardDataMap().get(rewardId);
|
||||||
|
int cardId = card.getRewardItemList().get(0).getItemId();
|
||||||
|
|
||||||
|
if (session.getPlayer().getNameCardList().contains(cardId)) {
|
||||||
|
// Already got divorce certificate.
|
||||||
|
session.getPlayer().sendPacket(new PacketAvatarFetterLevelRewardRsp(req.getAvatarGuid(), req.getFetterLevel(), rewardId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GenshinItem item = new GenshinItem(cardId);
|
||||||
|
session.getPlayer().getInventory().addItem(item);
|
||||||
|
session.getPlayer().sendPacket(new PacketItemAddHintNotify(item, ActionReason.FetterLevelReward));
|
||||||
|
session.getPlayer().sendPacket(new PacketUnlockNameCardNotify(cardId));
|
||||||
|
session.send(new PacketAvatarFetterLevelRewardRsp(avatarGuid, req.getFetterLevel(), rewardId));
|
||||||
|
session.send(new PacketAvatarFetterDataNotify(avatar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.avatar.GenshinAvatar;
|
||||||
|
import emu.grasscutter.game.props.FetterState;
|
||||||
|
import emu.grasscutter.net.packet.GenshinPacket;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify;
|
||||||
|
import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo;
|
||||||
|
import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData;
|
||||||
|
|
||||||
|
public class PacketAvatarFetterDataNotify extends GenshinPacket {
|
||||||
|
|
||||||
|
public PacketAvatarFetterDataNotify(GenshinAvatar avatar) {
|
||||||
|
super(PacketOpcodes.AvatarFetterDataNotify);
|
||||||
|
|
||||||
|
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder()
|
||||||
|
.setExpLevel(avatar.getFetterLevel())
|
||||||
|
.setExpNumber(avatar.getFetterExp());
|
||||||
|
|
||||||
|
if (avatar.getFetterList() != null) {
|
||||||
|
for (int i = 0; i < avatar.getFetterList().size(); i++) {
|
||||||
|
avatarFetter.addFetterList(
|
||||||
|
FetterData.newBuilder()
|
||||||
|
.setFetterId(avatar.getFetterList().get(i))
|
||||||
|
.setFetterState(FetterState.FINISH.getValue())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rewardId = avatar.getNameCardRewardId();
|
||||||
|
int cardId = avatar.getNameCardId();
|
||||||
|
|
||||||
|
if (avatar.getPlayer().getNameCardList().contains(cardId)) {
|
||||||
|
avatarFetter.addRewardedFetterLevelList(rewardId);
|
||||||
|
}
|
||||||
|
|
||||||
|
AvatarFetterInfo avatarFetterInfo = avatarFetter.build();
|
||||||
|
|
||||||
|
AvatarFetterDataNotify proto = AvatarFetterDataNotify.newBuilder()
|
||||||
|
.putFetterInfoMap(avatar.getGuid(), avatarFetterInfo)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.GenshinPacket;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp;
|
||||||
|
|
||||||
|
public class PacketAvatarFetterLevelRewardRsp extends GenshinPacket {
|
||||||
|
|
||||||
|
public PacketAvatarFetterLevelRewardRsp(long guid, int fetterLevel, int rewardId) {
|
||||||
|
super(PacketOpcodes.AvatarFetterLevelRewardRsp);
|
||||||
|
|
||||||
|
AvatarFetterLevelRewardRsp proto = AvatarFetterLevelRewardRsp.newBuilder()
|
||||||
|
.setAvatarGuid(guid)
|
||||||
|
.setFetterLevel(fetterLevel)
|
||||||
|
.setRetcode(0)
|
||||||
|
.setRewardId(rewardId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketAvatarFetterLevelRewardRsp(long guid, int fetterLevel) {
|
||||||
|
super(PacketOpcodes.AvatarFetterLevelRewardRsp);
|
||||||
|
|
||||||
|
AvatarFetterLevelRewardRsp proto = AvatarFetterLevelRewardRsp.newBuilder()
|
||||||
|
.setAvatarGuid(guid)
|
||||||
|
.setFetterLevel(fetterLevel)
|
||||||
|
.setRetcode(1)
|
||||||
|
.setRewardId(0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user