mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-27 14:28:22 +00:00
Merge branch 'development' of github.com:Grasscutters/Grasscutter into development
This commit is contained in:
commit
613366516d
16
proto/TowerBuffSelectReq.proto
Normal file
16
proto/TowerBuffSelectReq.proto
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message TowerBuffSelectReq {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
IS_ALLOW_CLIENT = 1;
|
||||||
|
CMD_ID = 2424;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 tower_buff_id = 1;
|
||||||
|
}
|
16
proto/TowerBuffSelectRsp.proto
Normal file
16
proto/TowerBuffSelectRsp.proto
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message TowerBuffSelectRsp {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
CMD_ID = 2491;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 retcode = 1;
|
||||||
|
uint32 tower_buff_id = 2;
|
||||||
|
}
|
17
proto/TowerCurLevelRecordChangeNotify.proto
Normal file
17
proto/TowerCurLevelRecordChangeNotify.proto
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "TowerCurLevelRecord.proto";
|
||||||
|
|
||||||
|
message TowerCurLevelRecordChangeNotify {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
CMD_ID = 2489;
|
||||||
|
}
|
||||||
|
|
||||||
|
TowerCurLevelRecord cur_level_record = 1;
|
||||||
|
}
|
16
proto/TowerEnterLevelReq.proto
Normal file
16
proto/TowerEnterLevelReq.proto
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message TowerEnterLevelReq {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
IS_ALLOW_CLIENT = 1;
|
||||||
|
CMD_ID = 2412;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 enter_point_id = 1;
|
||||||
|
}
|
18
proto/TowerEnterLevelRsp.proto
Normal file
18
proto/TowerEnterLevelRsp.proto
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message TowerEnterLevelRsp {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
CMD_ID = 2426;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 retcode = 1;
|
||||||
|
uint32 floor_id = 2;
|
||||||
|
uint32 level_index = 3;
|
||||||
|
repeated uint32 tower_buff_id_list = 4;
|
||||||
|
}
|
9
proto/TowerLevelStarCondData.proto
Normal file
9
proto/TowerLevelStarCondData.proto
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message TowerLevelStarCondData {
|
||||||
|
uint32 star_cond_index = 3;
|
||||||
|
uint32 cond_value = 4;
|
||||||
|
bool is_pause = 5;
|
||||||
|
}
|
19
proto/TowerLevelStarCondNotify.proto
Normal file
19
proto/TowerLevelStarCondNotify.proto
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "TowerLevelStarCondData.proto";
|
||||||
|
|
||||||
|
message TowerLevelStarCondNotify {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
CMD_ID = 2492;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 floor_id = 1;
|
||||||
|
uint32 level_index = 2;
|
||||||
|
repeated TowerLevelStarCondData cond_data_list = 3;
|
||||||
|
}
|
19
proto/TowerTeamSelectReq.proto
Normal file
19
proto/TowerTeamSelectReq.proto
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "TowerTeam.proto";
|
||||||
|
|
||||||
|
message TowerTeamSelectReq {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
IS_ALLOW_CLIENT = 1;
|
||||||
|
CMD_ID = 2401;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 floor_id = 1;
|
||||||
|
repeated TowerTeam tower_team_list = 2;
|
||||||
|
}
|
15
proto/TowerTeamSelectRsp.proto
Normal file
15
proto/TowerTeamSelectRsp.proto
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message TowerTeamSelectRsp {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
CMD_ID = 2494;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 retcode = 1;
|
||||||
|
}
|
@ -68,7 +68,9 @@ public class GameData {
|
|||||||
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<CombineData> combineDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<CombineData> combineDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<RewardPreviewData> rewardPreviewDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<RewardPreviewData> rewardPreviewDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<TowerLevelData> towerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||||
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
||||||
@ -311,4 +313,11 @@ public class GameData {
|
|||||||
public static Int2ObjectMap<CombineData> getCombineDataMap() {
|
public static Int2ObjectMap<CombineData> getCombineDataMap() {
|
||||||
return combineDataMap;
|
return combineDataMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<TowerFloorData> getTowerFloorDataMap(){
|
||||||
|
return towerFloorDataMap;
|
||||||
|
}
|
||||||
|
public static Int2ObjectMap<TowerLevelData> getTowerLevelDataMap(){
|
||||||
|
return towerLevelDataMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
73
src/main/java/emu/grasscutter/data/def/TowerFloorData.java
Normal file
73
src/main/java/emu/grasscutter/data/def/TowerFloorData.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package emu.grasscutter.data.def;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
|
||||||
|
@ResourceType(name = "TowerFloorExcelConfigData.json")
|
||||||
|
public class TowerFloorData extends GameResource {
|
||||||
|
|
||||||
|
private int FloorId;
|
||||||
|
private int FloorIndex;
|
||||||
|
private int LevelId;
|
||||||
|
private int OverrideMonsterLevel;
|
||||||
|
private int TeamNum;
|
||||||
|
private int FloorLevelConfigId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return this.FloorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
super.onLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFloorId() {
|
||||||
|
return FloorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFloorId(int floorId) {
|
||||||
|
FloorId = floorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFloorIndex() {
|
||||||
|
return FloorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFloorIndex(int floorIndex) {
|
||||||
|
FloorIndex = floorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevelId() {
|
||||||
|
return LevelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevelId(int levelId) {
|
||||||
|
LevelId = levelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOverrideMonsterLevel() {
|
||||||
|
return OverrideMonsterLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOverrideMonsterLevel(int overrideMonsterLevel) {
|
||||||
|
OverrideMonsterLevel = overrideMonsterLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTeamNum() {
|
||||||
|
return TeamNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTeamNum(int teamNum) {
|
||||||
|
TeamNum = teamNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFloorLevelConfigId() {
|
||||||
|
return FloorLevelConfigId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFloorLevelConfigId(int floorLevelConfigId) {
|
||||||
|
FloorLevelConfigId = floorLevelConfigId;
|
||||||
|
}
|
||||||
|
}
|
55
src/main/java/emu/grasscutter/data/def/TowerLevelData.java
Normal file
55
src/main/java/emu/grasscutter/data/def/TowerLevelData.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package emu.grasscutter.data.def;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
|
||||||
|
@ResourceType(name = "TowerLevelExcelConfigData.json")
|
||||||
|
public class TowerLevelData extends GameResource {
|
||||||
|
|
||||||
|
private int ID;
|
||||||
|
private int LevelId;
|
||||||
|
private int LevelIndex;
|
||||||
|
private int DungeonId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return this.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
super.onLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getID() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setID(int ID) {
|
||||||
|
this.ID = ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevelId() {
|
||||||
|
return LevelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevelId(int levelId) {
|
||||||
|
LevelId = levelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevelIndex() {
|
||||||
|
return LevelIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevelIndex(int levelIndex) {
|
||||||
|
LevelIndex = levelIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDungeonId() {
|
||||||
|
return DungeonId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDungeonId(int dungeonId) {
|
||||||
|
DungeonId = dungeonId;
|
||||||
|
}
|
||||||
|
}
|
@ -75,7 +75,8 @@ public class DungeonManager {
|
|||||||
prevPos.set(entry.getPointData().getTranPos());
|
prevPos.set(entry.getPointData().getTranPos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// clean temp team if it has
|
||||||
|
player.getTeamManager().cleanTemporaryTeam();
|
||||||
// Transfer player back to world
|
// Transfer player back to world
|
||||||
player.getWorld().transferPlayerToScene(player, prevScene, prevPos);
|
player.getWorld().transferPlayerToScene(player, prevScene, prevPos);
|
||||||
player.sendPacket(new BasePacket(PacketOpcodes.PlayerQuitDungeonRsp));
|
player.sendPacket(new BasePacket(PacketOpcodes.PlayerQuitDungeonRsp));
|
||||||
|
@ -0,0 +1,147 @@
|
|||||||
|
package emu.grasscutter.game.managers.SotSManager;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
|
import emu.grasscutter.net.proto.ChangeHpReasonOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.PropChangeReasonOuterClass;
|
||||||
|
import emu.grasscutter.server.game.GameSession;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketEntityFightPropChangeReasonNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
// Statue of the Seven Manager
|
||||||
|
public class SotSManager {
|
||||||
|
|
||||||
|
// NOTE: Spring volume balance *1 = fight prop HP *100
|
||||||
|
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
public SotSManager(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getIsAutoRecoveryEnabled() {
|
||||||
|
return player.getProperty(PlayerProperty.PROP_IS_SPRING_AUTO_USE) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsAutoRecoveryEnabled(boolean enabled) {
|
||||||
|
player.setProperty(PlayerProperty.PROP_IS_SPRING_AUTO_USE, enabled ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAutoRecoveryPercentage() {
|
||||||
|
return player.getProperty(PlayerProperty.PROP_SPRING_AUTO_USE_PERCENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoRecoveryPercentage(int percentage) {
|
||||||
|
player.setProperty(PlayerProperty.PROP_SPRING_AUTO_USE_PERCENT, percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// autoRevive automatically revives all team members.
|
||||||
|
public void autoRevive(GameSession session) {
|
||||||
|
player.getTeamManager().getActiveTeam().forEach(entity -> {
|
||||||
|
boolean isAlive = entity.isAlive();
|
||||||
|
if (!isAlive) {
|
||||||
|
float maxHP = entity.getAvatar().getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
||||||
|
float newHP = (float)(maxHP * 0.3);
|
||||||
|
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
|
||||||
|
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scheduleAutoRecover(GameSession session) {
|
||||||
|
// TODO: play audio effects? possibly client side? - client automatically plays.
|
||||||
|
// delay 2.5 seconds
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
Thread.sleep(2500);
|
||||||
|
autoRecover(session);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().error(e.getMessage());
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refillSpringVolume() {
|
||||||
|
// TODO: max spring volume depends on level of the statues in Mondstadt and Liyue.
|
||||||
|
// https://genshin-impact.fandom.com/wiki/Statue_of_The_Seven#:~:text=region%20of%20Inazuma.-,Statue%20Levels,-Upon%20first%20unlocking
|
||||||
|
player.setProperty(PlayerProperty.PROP_MAX_SPRING_VOLUME, 8500000);
|
||||||
|
|
||||||
|
long now = System.currentTimeMillis() / 1000;
|
||||||
|
long secondsSinceLastUsed = now - player.getSpringLastUsed();
|
||||||
|
float percentageRefilled = (float)secondsSinceLastUsed / 15 / 100; // 15s = 1% max volume
|
||||||
|
int maxVolume = player.getProperty(PlayerProperty.PROP_MAX_SPRING_VOLUME);
|
||||||
|
int currentVolume = player.getProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME);
|
||||||
|
if (currentVolume < maxVolume) {
|
||||||
|
int volumeRefilled = (int)(percentageRefilled * maxVolume);
|
||||||
|
int newVolume = currentVolume + volumeRefilled;
|
||||||
|
if (currentVolume + volumeRefilled > maxVolume) {
|
||||||
|
newVolume = maxVolume;
|
||||||
|
}
|
||||||
|
player.setProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME, newVolume);
|
||||||
|
}
|
||||||
|
player.setSpringLastUsed(now);
|
||||||
|
player.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// autoRecover checks player setting to see if auto recover is enabled, and refill HP to the predefined level.
|
||||||
|
public void autoRecover(GameSession session) {
|
||||||
|
// TODO: In MP, respect SotS settings from the HOST.
|
||||||
|
boolean isAutoRecoveryEnabled = getIsAutoRecoveryEnabled();
|
||||||
|
int autoRecoverPercentage = getAutoRecoveryPercentage();
|
||||||
|
Grasscutter.getLogger().debug("isAutoRecoveryEnabled: " + isAutoRecoveryEnabled + "\tautoRecoverPercentage: " + autoRecoverPercentage);
|
||||||
|
|
||||||
|
if (isAutoRecoveryEnabled) {
|
||||||
|
player.getTeamManager().getActiveTeam().forEach(entity -> {
|
||||||
|
float maxHP = entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
||||||
|
float currentHP = entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
||||||
|
if (currentHP == maxHP) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float targetHP = maxHP * autoRecoverPercentage / 100;
|
||||||
|
|
||||||
|
if (targetHP > currentHP) {
|
||||||
|
float needHP = targetHP - currentHP;
|
||||||
|
float needSV = needHP * 100; // convert HP needed to Spring Volume needed
|
||||||
|
|
||||||
|
int sotsSVBalance = player.getProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME);
|
||||||
|
if (sotsSVBalance >= needSV) {
|
||||||
|
// sufficient
|
||||||
|
sotsSVBalance -= needSV;
|
||||||
|
} else {
|
||||||
|
// insufficient balance
|
||||||
|
needSV = sotsSVBalance;
|
||||||
|
sotsSVBalance = 0;
|
||||||
|
}
|
||||||
|
player.setProperty(PlayerProperty.PROP_CUR_SPRING_VOLUME, sotsSVBalance);
|
||||||
|
player.setSpringLastUsed(System.currentTimeMillis() / 1000);
|
||||||
|
|
||||||
|
float newHP = currentHP + needSV / 100; // convert SV to HP
|
||||||
|
|
||||||
|
// TODO: Figure out why client shows current HP instead of added HP.
|
||||||
|
// Say an avatar had 12000 and now has 14000, it should show "2000".
|
||||||
|
// The client always show "+14000" which is incorrect.
|
||||||
|
|
||||||
|
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
|
||||||
|
session.send(new PacketEntityFightPropChangeReasonNotify(entity, FightProperty.FIGHT_PROP_CUR_HP,
|
||||||
|
newHP, List.of(3), PropChangeReasonOuterClass.PropChangeReason.PROP_CHANGE_STATUE_RECOVER,
|
||||||
|
ChangeHpReasonOuterClass.ChangeHpReason.ChangeHpAddStatue));
|
||||||
|
session.send(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
|
||||||
|
|
||||||
|
Avatar avatar = entity.getAvatar();
|
||||||
|
avatar.setCurrentHp(newHP);
|
||||||
|
session.send(new PacketAvatarFightPropUpdateNotify(avatar, FightProperty.FIGHT_PROP_CUR_HP));
|
||||||
|
player.save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -22,11 +22,13 @@ import emu.grasscutter.game.inventory.Inventory;
|
|||||||
import emu.grasscutter.game.mail.Mail;
|
import emu.grasscutter.game.mail.Mail;
|
||||||
import emu.grasscutter.game.mail.MailHandler;
|
import emu.grasscutter.game.mail.MailHandler;
|
||||||
import emu.grasscutter.game.managers.MovementManager.MovementManager;
|
import emu.grasscutter.game.managers.MovementManager.MovementManager;
|
||||||
|
import emu.grasscutter.game.managers.SotSManager.SotSManager;
|
||||||
import emu.grasscutter.game.props.ActionReason;
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
import emu.grasscutter.game.props.EntityType;
|
import emu.grasscutter.game.props.EntityType;
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
import emu.grasscutter.game.shop.ShopLimit;
|
import emu.grasscutter.game.shop.ShopLimit;
|
||||||
import emu.grasscutter.game.managers.MapMarkManager.*;
|
import emu.grasscutter.game.managers.MapMarkManager.*;
|
||||||
|
import emu.grasscutter.game.tower.TowerManager;
|
||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
import emu.grasscutter.game.world.World;
|
import emu.grasscutter.game.world.World;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
@ -88,7 +90,11 @@ public class Player {
|
|||||||
@Transient private MailHandler mailHandler;
|
@Transient private MailHandler mailHandler;
|
||||||
@Transient private MessageHandler messageHandler;
|
@Transient private MessageHandler messageHandler;
|
||||||
|
|
||||||
|
@Transient private SotSManager sotsManager;
|
||||||
|
|
||||||
private TeamManager teamManager;
|
private TeamManager teamManager;
|
||||||
|
|
||||||
|
private TowerManager towerManager;
|
||||||
private PlayerGachaInfo gachaInfo;
|
private PlayerGachaInfo gachaInfo;
|
||||||
private PlayerProfile playerProfile;
|
private PlayerProfile playerProfile;
|
||||||
private boolean showAvatar;
|
private boolean showAvatar;
|
||||||
@ -124,6 +130,8 @@ public class Player {
|
|||||||
private MapMarksManager mapMarksManager;
|
private MapMarksManager mapMarksManager;
|
||||||
@Transient private MovementManager movementManager;
|
@Transient private MovementManager movementManager;
|
||||||
|
|
||||||
|
private long springLastUsed;
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
|
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
|
||||||
@ -165,6 +173,7 @@ public class Player {
|
|||||||
this.messageHandler = null;
|
this.messageHandler = null;
|
||||||
this.mapMarksManager = new MapMarksManager();
|
this.mapMarksManager = new MapMarksManager();
|
||||||
this.movementManager = new MovementManager(this);
|
this.movementManager = new MovementManager(this);
|
||||||
|
this.sotsManager = new SotSManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// On player creation
|
// On player creation
|
||||||
@ -176,6 +185,7 @@ public class Player {
|
|||||||
this.nickname = "Traveler";
|
this.nickname = "Traveler";
|
||||||
this.signature = "";
|
this.signature = "";
|
||||||
this.teamManager = new TeamManager(this);
|
this.teamManager = new TeamManager(this);
|
||||||
|
this.towerManager = new TowerManager(this);
|
||||||
this.birthday = new PlayerBirthday();
|
this.birthday = new PlayerBirthday();
|
||||||
this.setProperty(PlayerProperty.PROP_PLAYER_LEVEL, 1);
|
this.setProperty(PlayerProperty.PROP_PLAYER_LEVEL, 1);
|
||||||
this.setProperty(PlayerProperty.PROP_IS_SPRING_AUTO_USE, 1);
|
this.setProperty(PlayerProperty.PROP_IS_SPRING_AUTO_USE, 1);
|
||||||
@ -192,6 +202,7 @@ public class Player {
|
|||||||
this.messageHandler = null;
|
this.messageHandler = null;
|
||||||
this.mapMarksManager = new MapMarksManager();
|
this.mapMarksManager = new MapMarksManager();
|
||||||
this.movementManager = new MovementManager(this);
|
this.movementManager = new MovementManager(this);
|
||||||
|
this.sotsManager = new SotSManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getUid() {
|
public int getUid() {
|
||||||
@ -389,6 +400,10 @@ public class Player {
|
|||||||
return this.teamManager;
|
return this.teamManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TowerManager getTowerManager() {
|
||||||
|
return towerManager;
|
||||||
|
}
|
||||||
|
|
||||||
public PlayerGachaInfo getGachaInfo() {
|
public PlayerGachaInfo getGachaInfo() {
|
||||||
return gachaInfo;
|
return gachaInfo;
|
||||||
}
|
}
|
||||||
@ -522,6 +537,14 @@ public class Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getSpringLastUsed() {
|
||||||
|
return springLastUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpringLastUsed(long val) {
|
||||||
|
springLastUsed = val;
|
||||||
|
}
|
||||||
|
|
||||||
public SceneLoadState getSceneLoadState() {
|
public SceneLoadState getSceneLoadState() {
|
||||||
return sceneState;
|
return sceneState;
|
||||||
}
|
}
|
||||||
@ -976,6 +999,8 @@ public class Player {
|
|||||||
|
|
||||||
public MovementManager getMovementManager() { return movementManager; }
|
public MovementManager getMovementManager() { return movementManager; }
|
||||||
|
|
||||||
|
public SotSManager getSotSManager() { return sotsManager; }
|
||||||
|
|
||||||
public synchronized void onTick() {
|
public synchronized void onTick() {
|
||||||
// Check ping
|
// Check ping
|
||||||
if (this.getLastPingTime() > System.currentTimeMillis() + 60000) {
|
if (this.getLastPingTime() > System.currentTimeMillis() + 60000) {
|
||||||
@ -1030,6 +1055,9 @@ public class Player {
|
|||||||
if (this.getProfile().getUid() == 0) {
|
if (this.getProfile().getUid() == 0) {
|
||||||
this.getProfile().syncWithCharacter(this);
|
this.getProfile().syncWithCharacter(this);
|
||||||
}
|
}
|
||||||
|
if (this.getTowerManager() == null) {
|
||||||
|
this.towerManager = new TowerManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if player object exists in server
|
// Check if player object exists in server
|
||||||
// TODO - optimize
|
// TODO - optimize
|
||||||
|
@ -18,6 +18,11 @@ public class TeamInfo {
|
|||||||
this.avatars = new ArrayList<>(Grasscutter.getConfig().getGameServerOptions().MaxAvatarsInTeam);
|
this.avatars = new ArrayList<>(Grasscutter.getConfig().getGameServerOptions().MaxAvatarsInTeam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TeamInfo(List<Integer> avatars) {
|
||||||
|
this.name = "";
|
||||||
|
this.avatars = avatars;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
package emu.grasscutter.game.player;
|
package emu.grasscutter.game.player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
import dev.morphia.annotations.Transient;
|
import dev.morphia.annotations.Transient;
|
||||||
@ -59,7 +53,13 @@ public class TeamManager {
|
|||||||
@Transient private final Set<EntityBaseGadget> gadgets;
|
@Transient private final Set<EntityBaseGadget> gadgets;
|
||||||
@Transient private final IntSet teamResonances;
|
@Transient private final IntSet teamResonances;
|
||||||
@Transient private final IntSet teamResonancesConfig;
|
@Transient private final IntSet teamResonancesConfig;
|
||||||
|
|
||||||
|
@Transient private int useTemporarilyTeamIndex = -1;
|
||||||
|
/**
|
||||||
|
* Temporary Team for tower
|
||||||
|
*/
|
||||||
|
@Transient private List<TeamInfo> temporaryTeam;
|
||||||
|
|
||||||
public TeamManager() {
|
public TeamManager() {
|
||||||
this.mpTeam = new TeamInfo();
|
this.mpTeam = new TeamInfo();
|
||||||
this.avatars = new ArrayList<>();
|
this.avatars = new ArrayList<>();
|
||||||
@ -125,6 +125,10 @@ public class TeamManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TeamInfo getCurrentTeamInfo() {
|
public TeamInfo getCurrentTeamInfo() {
|
||||||
|
if (useTemporarilyTeamIndex >= 0 &&
|
||||||
|
useTemporarilyTeamIndex < temporaryTeam.size()){
|
||||||
|
return temporaryTeam.get(useTemporarilyTeamIndex);
|
||||||
|
}
|
||||||
if (this.getPlayer().isInMultiplayer()) {
|
if (this.getPlayer().isInMultiplayer()) {
|
||||||
return this.getMpTeam();
|
return this.getMpTeam();
|
||||||
}
|
}
|
||||||
@ -352,7 +356,51 @@ public class TeamManager {
|
|||||||
// Packet
|
// Packet
|
||||||
this.updateTeamEntities(new PacketChangeMpTeamAvatarRsp(getPlayer(), teamInfo));
|
this.updateTeamEntities(new PacketChangeMpTeamAvatarRsp(getPlayer(), teamInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setupTemporaryTeam(List<List<Long>> guidList) {
|
||||||
|
var team = guidList.stream().map(list -> {
|
||||||
|
// Sanity checks
|
||||||
|
if (list.size() == 0 || list.size() > getMaxTeamSize()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set team data
|
||||||
|
LinkedHashSet<Avatar> newTeam = new LinkedHashSet<>();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Avatar avatar = getPlayer().getAvatars().getAvatarByGuid(list.get(i));
|
||||||
|
if (avatar == null || newTeam.contains(avatar)) {
|
||||||
|
// Should never happen
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
newTeam.add(avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to avatar ids
|
||||||
|
return newTeam.stream()
|
||||||
|
.map(Avatar::getAvatarId)
|
||||||
|
.toList();
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(TeamInfo::new)
|
||||||
|
.toList();
|
||||||
|
this.temporaryTeam = team;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void useTemporaryTeam(int index) {
|
||||||
|
this.useTemporarilyTeamIndex = index;
|
||||||
|
updateTeamEntities(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanTemporaryTeam() {
|
||||||
|
// check if using temporary team
|
||||||
|
if(useTemporarilyTeamIndex < 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.useTemporarilyTeamIndex = -1;
|
||||||
|
this.temporaryTeam = null;
|
||||||
|
updateTeamEntities(null);
|
||||||
|
}
|
||||||
public synchronized void setCurrentTeam(int teamId) {
|
public synchronized void setCurrentTeam(int teamId) {
|
||||||
//
|
//
|
||||||
if (getPlayer().isInMultiplayer()) {
|
if (getPlayer().isInMultiplayer()) {
|
||||||
|
42
src/main/java/emu/grasscutter/game/tower/TowerManager.java
Normal file
42
src/main/java/emu/grasscutter/game/tower/TowerManager.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package emu.grasscutter.game.tower;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import dev.morphia.annotations.Transient;
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketTowerEnterLevelRsp;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class TowerManager {
|
||||||
|
@Transient private final Player player;
|
||||||
|
|
||||||
|
public TowerManager(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int currentLevel;
|
||||||
|
private int currentFloor;
|
||||||
|
|
||||||
|
public void teamSelect(int floor, List<List<Long>> towerTeams) {
|
||||||
|
var floorData = GameData.getTowerFloorDataMap().get(floor);
|
||||||
|
|
||||||
|
this.currentFloor = floorData.getFloorId();
|
||||||
|
this.currentLevel = floorData.getLevelId();
|
||||||
|
|
||||||
|
player.getTeamManager().setupTemporaryTeam(towerTeams);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void enterLevel(int enterPointId) {
|
||||||
|
var levelData = GameData.getTowerLevelDataMap().get(currentLevel);
|
||||||
|
var id = levelData.getDungeonId();
|
||||||
|
// use team user choose
|
||||||
|
player.getTeamManager().useTemporaryTeam(0);
|
||||||
|
player.getServer().getDungeonManager()
|
||||||
|
.enterDungeon(player, enterPointId, id);
|
||||||
|
|
||||||
|
player.getSession().send(new PacketTowerEnterLevelRsp(currentFloor, currentLevel));
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
package emu.grasscutter.net.packet;
|
package emu.grasscutter.net.packet;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class PacketOpcodes {
|
public class PacketOpcodes {
|
||||||
// Empty
|
// Empty
|
||||||
public static final int NONE = 0;
|
public static final int NONE = 0;
|
||||||
@ -1566,4 +1569,6 @@ public class PacketOpcodes {
|
|||||||
public static final int UNKNOWN_43 = 8877;
|
public static final int UNKNOWN_43 = 8877;
|
||||||
public static final int UNKNOWN_44 = 8983;
|
public static final int UNKNOWN_44 = 8983;
|
||||||
public static final int UNKNOWN_45 = 943;
|
public static final int UNKNOWN_45 = 943;
|
||||||
|
|
||||||
|
public static final List<Integer> BANNED_PACKETS = Arrays.asList(PacketOpcodes.WindSeedClientNotify, PacketOpcodes.PlayerLuaShellNotify);
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,12 @@ public class GameSession extends KcpChannel {
|
|||||||
Grasscutter.getLogger().warn("Tried to send packet with missing cmd id!");
|
Grasscutter.getLogger().warn("Tried to send packet with missing cmd id!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DO NOT REMOVE (unless we find a way to validate code before sending to client which I don't think we can)
|
||||||
|
// Stop WindSeedClientNotify from being sent for security purposes.
|
||||||
|
if(PacketOpcodes.BANNED_PACKETS.contains(packet.getOpcode())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
if (packet.shouldBuildHeader()) {
|
if (packet.shouldBuildHeader()) {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.managers.SotSManager.SotSManager;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
@ -18,26 +20,12 @@ import java.util.List;
|
|||||||
public class HandlerEnterTransPointRegionNotify extends PacketHandler {
|
public class HandlerEnterTransPointRegionNotify extends PacketHandler {
|
||||||
@Override
|
@Override
|
||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception{
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception{
|
||||||
session.getPlayer().getTeamManager().getActiveTeam().forEach(entity -> {
|
Player player = session.getPlayer();
|
||||||
boolean isAlive = entity.isAlive();
|
SotSManager sotsManager = player.getSotSManager();
|
||||||
if(entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) != entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)){
|
|
||||||
Float hp = entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)-entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
|
||||||
|
|
||||||
session.send(new PacketEntityFightPropUpdateNotify(entity,FightProperty.FIGHT_PROP_MAX_HP));
|
|
||||||
|
|
||||||
session.send(new PacketEntityFightPropChangeReasonNotify(
|
sotsManager.refillSpringVolume();
|
||||||
entity, FightProperty.FIGHT_PROP_CUR_HP, hp, List.of(3),
|
sotsManager.autoRevive(session);
|
||||||
PropChangeReason.PROP_CHANGE_STATUE_RECOVER, ChangeHpReason.ChangeHpAddStatue));
|
sotsManager.scheduleAutoRecover(session);
|
||||||
|
// TODO: allow interaction with the SotS?
|
||||||
entity.setFightProperty(
|
|
||||||
FightProperty.FIGHT_PROP_CUR_HP,
|
|
||||||
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)
|
|
||||||
);
|
|
||||||
session.send(new PacketAvatarFightPropUpdateNotify(entity.getAvatar(), FightProperty.FIGHT_PROP_CUR_HP));
|
|
||||||
if (!isAlive) {
|
|
||||||
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.TowerEnterLevelReqOuterClass.TowerEnterLevelReq;
|
||||||
|
import emu.grasscutter.server.game.GameSession;
|
||||||
|
|
||||||
|
@Opcodes(PacketOpcodes.TowerEnterLevelReq)
|
||||||
|
public class HandlerTowerEnterLevelReq extends PacketHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
|
TowerEnterLevelReq req = TowerEnterLevelReq.parseFrom(payload);
|
||||||
|
|
||||||
|
//session.send(new PacketTowerCurLevelRecordChangeNotify());
|
||||||
|
session.getPlayer().getTowerManager().enterLevel(req.getEnterPointId());
|
||||||
|
|
||||||
|
//session.send(new PacketTowerLevelStarCondNotify());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.TowerTeamOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.TowerTeamSelectReqOuterClass.TowerTeamSelectReq;
|
||||||
|
import emu.grasscutter.server.game.GameSession;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketTowerTeamSelectRsp;
|
||||||
|
|
||||||
|
@Opcodes(PacketOpcodes.TowerTeamSelectReq)
|
||||||
|
public class HandlerTowerTeamSelectReq extends PacketHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
|
TowerTeamSelectReq req = TowerTeamSelectReq.parseFrom(payload);
|
||||||
|
|
||||||
|
var towerTeams = req.getTowerTeamListList().stream()
|
||||||
|
.map(TowerTeamOuterClass.TowerTeam::getAvatarGuidListList)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
session.getPlayer().getTowerManager().teamSelect(req.getFloorId(), towerTeams);
|
||||||
|
|
||||||
|
session.send(new PacketTowerTeamSelectRsp());
|
||||||
|
}
|
||||||
|
}
|
@ -15,14 +15,7 @@ public class PacketTakeAchievementRewardReq extends BasePacket {
|
|||||||
public PacketTakeAchievementRewardReq(GameSession session) {
|
public PacketTakeAchievementRewardReq(GameSession session) {
|
||||||
super(PacketOpcodes.TakeAchievementRewardReq);
|
super(PacketOpcodes.TakeAchievementRewardReq);
|
||||||
|
|
||||||
List<AchievementInfo> a_list = new ArrayList<>();
|
TakeAchievementRewardReq proto = TakeAchievementRewardReq.newBuilder().build();
|
||||||
a_list.add(AchievementInfo.newBuilder().setId(82044).setStatusValue(2).setCurrent(0).setGoal(1).build());
|
|
||||||
a_list.add(AchievementInfo.newBuilder().setId(81205).setStatusValue(2).setCurrent(0).setGoal(1).build());
|
|
||||||
|
|
||||||
|
|
||||||
TakeAchievementRewardReq proto = TakeAchievementRewardReq.newBuilder()
|
|
||||||
.addAllAList(a_list)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,28 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.def.TowerFloorData;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.TowerAllDataRspOuterClass.TowerAllDataRsp;
|
import emu.grasscutter.net.proto.TowerAllDataRspOuterClass.TowerAllDataRsp;
|
||||||
import emu.grasscutter.net.proto.TowerCurLevelRecordOuterClass.TowerCurLevelRecord;
|
import emu.grasscutter.net.proto.TowerCurLevelRecordOuterClass.TowerCurLevelRecord;
|
||||||
import emu.grasscutter.net.proto.TowerFloorRecordOuterClass.TowerFloorRecord;
|
import emu.grasscutter.net.proto.TowerFloorRecordOuterClass.TowerFloorRecord;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class PacketTowerAllDataRsp extends BasePacket {
|
public class PacketTowerAllDataRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketTowerAllDataRsp() {
|
public PacketTowerAllDataRsp() {
|
||||||
super(PacketOpcodes.TowerAllDataRsp);
|
super(PacketOpcodes.TowerAllDataRsp);
|
||||||
|
|
||||||
|
var list = GameData.getTowerFloorDataMap().values().stream()
|
||||||
|
.map(TowerFloorData::getFloorId)
|
||||||
|
.map(id -> TowerFloorRecord.newBuilder().setFloorId(id).build())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
TowerAllDataRsp proto = TowerAllDataRsp.newBuilder()
|
TowerAllDataRsp proto = TowerAllDataRsp.newBuilder()
|
||||||
.setTowerScheduleId(29)
|
.setTowerScheduleId(29)
|
||||||
.addTowerFloorRecordList(TowerFloorRecord.newBuilder().setFloorId(1001))
|
.addAllTowerFloorRecordList(list)
|
||||||
.setCurLevelRecord(TowerCurLevelRecord.newBuilder().setIsEmpty(true))
|
.setCurLevelRecord(TowerCurLevelRecord.newBuilder().setIsEmpty(true))
|
||||||
.setNextScheduleChangeTime(Integer.MAX_VALUE)
|
.setNextScheduleChangeTime(Integer.MAX_VALUE)
|
||||||
.putFloorOpenTimeMap(1024, 1630486800)
|
.putFloorOpenTimeMap(1024, 1630486800)
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.TowerEnterLevelRspOuterClass.TowerEnterLevelRsp;
|
||||||
|
|
||||||
|
public class PacketTowerEnterLevelRsp extends BasePacket {
|
||||||
|
|
||||||
|
public PacketTowerEnterLevelRsp(int floorId, int levelIndex) {
|
||||||
|
super(PacketOpcodes.TowerEnterLevelRsp);
|
||||||
|
|
||||||
|
TowerEnterLevelRsp proto = TowerEnterLevelRsp.newBuilder()
|
||||||
|
.setFloorId(floorId)
|
||||||
|
.setLevelIndex(levelIndex)
|
||||||
|
.addTowerBuffIdList(4)
|
||||||
|
.addTowerBuffIdList(28)
|
||||||
|
.addTowerBuffIdList(18)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
|
import emu.grasscutter.net.proto.TowerTeamSelectRspOuterClass.TowerTeamSelectRsp;
|
||||||
|
|
||||||
|
public class PacketTowerTeamSelectRsp extends BasePacket {
|
||||||
|
|
||||||
|
public PacketTowerTeamSelectRsp() {
|
||||||
|
super(PacketOpcodes.TowerTeamSelectRsp);
|
||||||
|
|
||||||
|
TowerTeamSelectRsp proto = TowerTeamSelectRsp.newBuilder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.setData(proto);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user