mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-06-26 18:14:50 +08:00
Compare commits
40 Commits
99bcd2af70
...
af6c27a002
Author | SHA1 | Date | |
---|---|---|---|
|
af6c27a002 | ||
|
45438cd2a7 | ||
|
4501db1135 | ||
|
9daf89b953 | ||
|
50f0a38e21 | ||
|
51df48ee14 | ||
|
1ebd8f6810 | ||
|
1b9e39dcab | ||
|
89ba8f5d01 | ||
|
148395de67 | ||
|
d35ff068cf | ||
|
a695d0c33e | ||
|
1c0d869ee5 | ||
|
5d0610b6f2 | ||
|
e1770b5a68 | ||
|
862bfa0611 | ||
|
57260415b0 | ||
|
233b46b2f9 | ||
|
db8cbd4f83 | ||
|
f876470369 | ||
|
29941aa8d0 | ||
|
5f8cc47e87 | ||
|
3feb98f08b | ||
|
4ef3080c62 | ||
|
89454726ac | ||
|
8faf8decec | ||
|
1fef837a97 | ||
|
3902a5d744 | ||
|
2e24d77bc2 | ||
|
9902ba381a | ||
|
f53dda0335 | ||
|
73a88b2da2 | ||
|
17a273387e | ||
|
7c02e6c912 | ||
|
e43946e44c | ||
|
3f27874765 | ||
|
c103841a03 | ||
|
a63ed21213 | ||
|
035b0ff8bd | ||
|
8a7077dc04 |
@ -76,7 +76,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation group: 'org.reflections', name: 'reflections', version: '0.10.2'
|
implementation group: 'org.reflections', name: 'reflections', version: '0.10.2'
|
||||||
|
|
||||||
implementation group: 'dev.morphia.morphia', name: 'morphia-core', version: '2.2.6'
|
implementation group: 'dev.morphia.morphia', name: 'morphia-core', version: '2.2.7'
|
||||||
|
|
||||||
implementation group: 'org.greenrobot', name: 'eventbus-java', version: '3.3.1'
|
implementation group: 'org.greenrobot', name: 'eventbus-java', version: '3.3.1'
|
||||||
implementation group: 'org.danilopianini', name: 'java-quadtree', version: '0.1.9'
|
implementation group: 'org.danilopianini', name: 'java-quadtree', version: '0.1.9'
|
||||||
@ -86,6 +86,9 @@ dependencies {
|
|||||||
|
|
||||||
implementation group: 'org.luaj', name: 'luaj-jse', version: '3.0.1'
|
implementation group: 'org.luaj', name: 'luaj-jse', version: '3.0.1'
|
||||||
|
|
||||||
|
implementation group: 'com.esotericsoftware', name : 'reflectasm', version: '1.11.9'
|
||||||
|
implementation group: 'com.github.davidmoten', name : 'rtree-multi', version: '0.1'
|
||||||
|
|
||||||
protobuf files('proto/')
|
protobuf files('proto/')
|
||||||
|
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.24'
|
compileOnly 'org.projectlombok:lombok:1.18.24'
|
||||||
|
12
proto/DailyDungeonEntryInfo.proto
Normal file
12
proto/DailyDungeonEntryInfo.proto
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "DungeonEntryInfo.proto";
|
||||||
|
|
||||||
|
message DailyDungeonEntryInfo {
|
||||||
|
uint32 dungeon_entry_id = 1;
|
||||||
|
uint32 dungeon_entry_config_id = 2;
|
||||||
|
uint32 recommend_dungeon_id = 3;
|
||||||
|
DungeonEntryInfo recommend_dungeon_entry_info = 4;
|
||||||
|
}
|
12
proto/FurnitureCurModuleArrangeCountNotify.proto
Normal file
12
proto/FurnitureCurModuleArrangeCountNotify.proto
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "Uint32Pair.proto";
|
||||||
|
|
||||||
|
// CmdId: 4681
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message FurnitureCurModuleArrangeCountNotify {
|
||||||
|
repeated Uint32Pair furniture_arrange_count_list = 9;
|
||||||
|
}
|
13
proto/FurnitureMakeBeHelpedData.proto
Normal file
13
proto/FurnitureMakeBeHelpedData.proto
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "ProfilePicture.proto";
|
||||||
|
|
||||||
|
message FurnitureMakeBeHelpedData {
|
||||||
|
string player_name = 1;
|
||||||
|
uint32 time = 2;
|
||||||
|
uint32 uid = 3;
|
||||||
|
uint32 icon = 4;
|
||||||
|
ProfilePicture profile_picture = 5;
|
||||||
|
}
|
12
proto/FurnitureMakeData.proto
Normal file
12
proto/FurnitureMakeData.proto
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message FurnitureMakeData {
|
||||||
|
uint32 index = 1;
|
||||||
|
uint32 make_id = 2;
|
||||||
|
uint32 begin_time = 3;
|
||||||
|
uint32 dur_time = 4;
|
||||||
|
uint32 accelerate_time = 5;
|
||||||
|
uint32 avatar_id = 6;
|
||||||
|
}
|
8
proto/FurnitureMakeHelpData.proto
Normal file
8
proto/FurnitureMakeHelpData.proto
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message FurnitureMakeHelpData {
|
||||||
|
uint32 uid = 1;
|
||||||
|
uint32 times = 2;
|
||||||
|
}
|
8
proto/FurnitureMakeMakeInfo.proto
Normal file
8
proto/FurnitureMakeMakeInfo.proto
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message FurnitureMakeMakeInfo {
|
||||||
|
uint32 furniture_id = 1;
|
||||||
|
uint32 make_count = 2;
|
||||||
|
}
|
10
proto/FurnitureMakeReq.proto
Normal file
10
proto/FurnitureMakeReq.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4551
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message FurnitureMakeReq {
|
||||||
|
}
|
19
proto/FurnitureMakeRsp.proto
Normal file
19
proto/FurnitureMakeRsp.proto
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "FurnitureMakeBeHelpedData.proto";
|
||||||
|
import "FurnitureMakeHelpData.proto";
|
||||||
|
import "FurnitureMakeMakeInfo.proto";
|
||||||
|
import "FurnitureMakeSlot.proto";
|
||||||
|
|
||||||
|
// CmdId: 4530
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message FurnitureMakeRsp {
|
||||||
|
int32 retcode = 6;
|
||||||
|
FurnitureMakeSlot furniture_make_slot = 10;
|
||||||
|
repeated FurnitureMakeHelpData help_data_list = 13;
|
||||||
|
repeated FurnitureMakeBeHelpedData helped_data_list = 12;
|
||||||
|
repeated FurnitureMakeMakeInfo make_info_list = 11;
|
||||||
|
}
|
9
proto/FurnitureMakeSlot.proto
Normal file
9
proto/FurnitureMakeSlot.proto
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "FurnitureMakeData.proto";
|
||||||
|
|
||||||
|
message FurnitureMakeSlot {
|
||||||
|
repeated FurnitureMakeData furniture_make_data_list = 1;
|
||||||
|
}
|
12
proto/FurnitureMakeStartReq.proto
Normal file
12
proto/FurnitureMakeStartReq.proto
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4582
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message FurnitureMakeStartReq {
|
||||||
|
uint32 make_id = 1;
|
||||||
|
uint32 avatar_id = 14;
|
||||||
|
}
|
13
proto/FurnitureMakeStartRsp.proto
Normal file
13
proto/FurnitureMakeStartRsp.proto
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "FurnitureMakeSlot.proto";
|
||||||
|
|
||||||
|
// CmdId: 4463
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message FurnitureMakeStartRsp {
|
||||||
|
int32 retcode = 8;
|
||||||
|
FurnitureMakeSlot furniture_make_slot = 10;
|
||||||
|
}
|
11
proto/GetDailyDungeonEntryInfoReq.proto
Normal file
11
proto/GetDailyDungeonEntryInfoReq.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 929
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message GetDailyDungeonEntryInfoReq {
|
||||||
|
uint32 scene_id = 11;
|
||||||
|
}
|
13
proto/GetDailyDungeonEntryInfoRsp.proto
Normal file
13
proto/GetDailyDungeonEntryInfoRsp.proto
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "DailyDungeonEntryInfo.proto";
|
||||||
|
|
||||||
|
// CmdId: 925
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message GetDailyDungeonEntryInfoRsp {
|
||||||
|
int32 retcode = 9;
|
||||||
|
repeated DailyDungeonEntryInfo daily_dungeon_info_list = 4;
|
||||||
|
}
|
10
proto/GetFurnitureCurModuleArrangeCountReq.proto
Normal file
10
proto/GetFurnitureCurModuleArrangeCountReq.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4603
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message GetFurnitureCurModuleArrangeCountReq {
|
||||||
|
}
|
16
proto/GetInvestigationMonsterReq.proto
Normal file
16
proto/GetInvestigationMonsterReq.proto
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message GetInvestigationMonsterReq {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
IS_ALLOW_CLIENT = 1;
|
||||||
|
CMD_ID = 1916;
|
||||||
|
}
|
||||||
|
|
||||||
|
repeated uint32 city_id_list = 1;
|
||||||
|
}
|
19
proto/GetInvestigationMonsterRsp.proto
Normal file
19
proto/GetInvestigationMonsterRsp.proto
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "InvestigationMonster.proto";
|
||||||
|
|
||||||
|
message GetInvestigationMonsterRsp {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
IS_ALLOW_CLIENT = 1;
|
||||||
|
CMD_ID = 1928;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 retcode = 1;
|
||||||
|
repeated InvestigationMonster monster_list = 2;
|
||||||
|
}
|
10
proto/GetPlayerHomeCompInfoReq.proto
Normal file
10
proto/GetPlayerHomeCompInfoReq.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4845
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message GetPlayerHomeCompInfoReq {
|
||||||
|
}
|
15
proto/GroupSuiteNotify.proto
Normal file
15
proto/GroupSuiteNotify.proto
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message GroupSuiteNotify {
|
||||||
|
enum CmdId {
|
||||||
|
option allow_alias = true;
|
||||||
|
NONE = 0;
|
||||||
|
ENET_CHANNEL_ID = 0;
|
||||||
|
ENET_IS_RELIABLE = 1;
|
||||||
|
CMD_ID = 3098;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<uint32, uint32> group_map = 1;
|
||||||
|
}
|
11
proto/HomeAnimalData.proto
Normal file
11
proto/HomeAnimalData.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeAnimalData {
|
||||||
|
uint32 furniture_id = 1;
|
||||||
|
Vector spawn_pos = 2;
|
||||||
|
Vector spawn_rot = 3;
|
||||||
|
}
|
16
proto/HomeBasicInfo.proto
Normal file
16
proto/HomeBasicInfo.proto
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "HomeLimitedShopInfo.proto";
|
||||||
|
|
||||||
|
message HomeBasicInfo {
|
||||||
|
uint32 cur_module_id = 1;
|
||||||
|
uint32 cur_room_scene_id = 2;
|
||||||
|
bool is_in_edit_mode = 3;
|
||||||
|
uint64 exp = 4;
|
||||||
|
uint32 level = 5;
|
||||||
|
uint32 home_owner_uid = 6;
|
||||||
|
HomeLimitedShopInfo limited_shop_info = 7;
|
||||||
|
string owner_nick_name = 8;
|
||||||
|
}
|
12
proto/HomeBasicInfoNotify.proto
Normal file
12
proto/HomeBasicInfoNotify.proto
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "HomeBasicInfo.proto";
|
||||||
|
|
||||||
|
// CmdId: 4872
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message HomeBasicInfoNotify {
|
||||||
|
HomeBasicInfo basic_info = 9;
|
||||||
|
}
|
29
proto/HomeBlockArrangementInfo.proto
Normal file
29
proto/HomeBlockArrangementInfo.proto
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
//import "BIEMCDLIFOD.proto";
|
||||||
|
//import "GOHMLAFNBGF.proto";
|
||||||
|
import "HomeAnimalData.proto";
|
||||||
|
import "HomeBlockDotPattern.proto";
|
||||||
|
import "HomeBlockFieldData.proto";
|
||||||
|
import "HomeFurnitureData.proto";
|
||||||
|
import "HomeFurnitureSuiteData.proto";
|
||||||
|
import "HomeNpcData.proto";
|
||||||
|
//import "WeekendDjinnInfo.proto";
|
||||||
|
|
||||||
|
message HomeBlockArrangementInfo {
|
||||||
|
uint32 block_id = 1;
|
||||||
|
repeated HomeFurnitureData persistent_furniture_list = 2;
|
||||||
|
repeated HomeFurnitureData deploy_furniure_list = 3;
|
||||||
|
repeated HomeNpcData deploy_npc_list = 4;
|
||||||
|
repeated HomeFurnitureSuiteData furniture_suite_list = 5;
|
||||||
|
repeated HomeAnimalData deploy_animal_list = 6;
|
||||||
|
bool is_unlocked = 7;
|
||||||
|
uint32 comfort_value = 8;
|
||||||
|
//repeated WeekendDjinnInfo weekend_djinn_info_list = 9;
|
||||||
|
repeated HomeBlockDotPattern dot_pattern_list = 10;
|
||||||
|
repeated HomeBlockFieldData field_list = 11;
|
||||||
|
// repeated GOHMLAFNBGF BOCBLHLEKNJ = 12;
|
||||||
|
// repeated BIEMCDLIFOD CONIAKDJHAN = 13;
|
||||||
|
}
|
9
proto/HomeBlockDotPattern.proto
Normal file
9
proto/HomeBlockDotPattern.proto
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message HomeBlockDotPattern {
|
||||||
|
uint32 height = 1;
|
||||||
|
uint32 width = 2;
|
||||||
|
bytes data = 3;
|
||||||
|
}
|
14
proto/HomeBlockFieldData.proto
Normal file
14
proto/HomeBlockFieldData.proto
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "HomeBlockSubFieldData.proto";
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeBlockFieldData {
|
||||||
|
uint32 guid = 1;
|
||||||
|
uint32 furniture_id = 2;
|
||||||
|
Vector pos = 3;
|
||||||
|
Vector rot = 4;
|
||||||
|
repeated HomeBlockSubFieldData sub_field_list = 5;
|
||||||
|
}
|
10
proto/HomeBlockNotify.proto
Normal file
10
proto/HomeBlockNotify.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4542
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message HomeBlockNotify {
|
||||||
|
uint32 end_time = 7;
|
||||||
|
}
|
10
proto/HomeBlockSubFieldData.proto
Normal file
10
proto/HomeBlockSubFieldData.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeBlockSubFieldData {
|
||||||
|
Vector pos = 1;
|
||||||
|
Vector rot = 2;
|
||||||
|
}
|
11
proto/HomeChangeEditModeReq.proto
Normal file
11
proto/HomeChangeEditModeReq.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4625
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message HomeChangeEditModeReq {
|
||||||
|
bool is_enter_edit_mode = 5;
|
||||||
|
}
|
11
proto/HomeChangeEditModeRsp.proto
Normal file
11
proto/HomeChangeEditModeRsp.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4885
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message HomeChangeEditModeRsp {
|
||||||
|
int32 retcode = 11;
|
||||||
|
bool is_enter_edit_mode = 5;
|
||||||
|
}
|
14
proto/HomeFurnitureData.proto
Normal file
14
proto/HomeFurnitureData.proto
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeFurnitureData {
|
||||||
|
uint32 furniture_id = 1;
|
||||||
|
Vector spawn_pos = 3;
|
||||||
|
Vector spawn_rot = 4;
|
||||||
|
int32 parent_furniture_index = 7;
|
||||||
|
uint32 guid = 8;
|
||||||
|
uint32 version = 9;
|
||||||
|
}
|
13
proto/HomeFurnitureSuiteData.proto
Normal file
13
proto/HomeFurnitureSuiteData.proto
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeFurnitureSuiteData {
|
||||||
|
uint32 suite_id = 1;
|
||||||
|
Vector spawn_pos = 2;
|
||||||
|
repeated int32 included_furniture_index_list = 3;
|
||||||
|
uint32 guid = 5;
|
||||||
|
bool is_allow_summon = 6;
|
||||||
|
}
|
11
proto/HomeGetArrangementInfoReq.proto
Normal file
11
proto/HomeGetArrangementInfoReq.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4848
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message HomeGetArrangementInfoReq {
|
||||||
|
repeated uint32 scene_id_list = 6;
|
||||||
|
}
|
13
proto/HomeGetArrangementInfoRsp.proto
Normal file
13
proto/HomeGetArrangementInfoRsp.proto
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "HomeSceneArrangementInfo.proto";
|
||||||
|
|
||||||
|
// CmdId: 4456
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message HomeGetArrangementInfoRsp {
|
||||||
|
int32 retcode = 1;
|
||||||
|
repeated HomeSceneArrangementInfo scene_arrangement_info_list = 12;
|
||||||
|
}
|
10
proto/HomeGetBasicInfoReq.proto
Normal file
10
proto/HomeGetBasicInfoReq.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4535
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message HomeGetBasicInfoReq {
|
||||||
|
}
|
14
proto/HomeLimitedShopInfo.proto
Normal file
14
proto/HomeLimitedShopInfo.proto
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeLimitedShopInfo {
|
||||||
|
uint32 uid = 1;
|
||||||
|
uint32 next_open_time = 3;
|
||||||
|
uint32 next_guest_open_time = 4;
|
||||||
|
uint32 next_close_time = 5;
|
||||||
|
Vector djinn_pos = 6;
|
||||||
|
Vector djinn_rot = 7;
|
||||||
|
}
|
18
proto/HomeMarkPointFurnitureData.proto
Normal file
18
proto/HomeMarkPointFurnitureData.proto
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "HomeMarkPointNPCData.proto";
|
||||||
|
import "HomeMarkPointSuiteData.proto";
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeMarkPointFurnitureData {
|
||||||
|
uint32 guid = 1;
|
||||||
|
uint32 furniture_id = 2;
|
||||||
|
uint32 furniture_type = 3;
|
||||||
|
Vector pos = 4;
|
||||||
|
oneof extra {
|
||||||
|
HomeMarkPointNPCData npc_data = 6;
|
||||||
|
HomeMarkPointSuiteData suite_data = 7;
|
||||||
|
}
|
||||||
|
}
|
8
proto/HomeMarkPointNPCData.proto
Normal file
8
proto/HomeMarkPointNPCData.proto
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message HomeMarkPointNPCData {
|
||||||
|
uint32 avatar_id = 1;
|
||||||
|
uint32 costume_id = 2;
|
||||||
|
}
|
12
proto/HomeMarkPointNotify.proto
Normal file
12
proto/HomeMarkPointNotify.proto
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "HomeMarkPointSceneData.proto";
|
||||||
|
|
||||||
|
// CmdId: 4746
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message HomeMarkPointNotify {
|
||||||
|
repeated HomeMarkPointSceneData mark_point_data_list = 13;
|
||||||
|
}
|
13
proto/HomeMarkPointSceneData.proto
Normal file
13
proto/HomeMarkPointSceneData.proto
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "HomeMarkPointFurnitureData.proto";
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeMarkPointSceneData {
|
||||||
|
uint32 module_id = 1;
|
||||||
|
uint32 scene_id = 2;
|
||||||
|
repeated HomeMarkPointFurnitureData furniture_list = 3;
|
||||||
|
Vector teapot_spirit_pos = 4;
|
||||||
|
}
|
7
proto/HomeMarkPointSuiteData.proto
Normal file
7
proto/HomeMarkPointSuiteData.proto
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message HomeMarkPointSuiteData {
|
||||||
|
uint32 suite_id = 1;
|
||||||
|
}
|
12
proto/HomeNpcData.proto
Normal file
12
proto/HomeNpcData.proto
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeNpcData {
|
||||||
|
uint32 avatar_id = 1;
|
||||||
|
Vector spawn_pos = 2;
|
||||||
|
Vector spawn_rot = 3;
|
||||||
|
uint32 costume_id = 4;
|
||||||
|
}
|
22
proto/HomeSceneArrangementInfo.proto
Normal file
22
proto/HomeSceneArrangementInfo.proto
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "HomeBlockArrangementInfo.proto";
|
||||||
|
import "HomeFurnitureData.proto";
|
||||||
|
import "Vector.proto";
|
||||||
|
|
||||||
|
message HomeSceneArrangementInfo {
|
||||||
|
uint32 scene_id = 1;
|
||||||
|
repeated HomeBlockArrangementInfo block_arrangement_info_list = 2;
|
||||||
|
bool is_set_born_pos = 3;
|
||||||
|
Vector born_pos = 4;
|
||||||
|
Vector born_rot = 5;
|
||||||
|
repeated HomeFurnitureData door_list = 7;
|
||||||
|
repeated HomeFurnitureData stair_list = 8;
|
||||||
|
HomeFurnitureData main_house = 9;
|
||||||
|
uint32 comfort_value = 10;
|
||||||
|
Vector djinn_pos = 11;
|
||||||
|
uint32 tmp_version = 12;
|
||||||
|
uint32 CNLMNOEGKME = 13;
|
||||||
|
}
|
10
proto/HomeSceneInitFinishReq.proto
Normal file
10
proto/HomeSceneInitFinishReq.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4552
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message HomeSceneInitFinishReq {
|
||||||
|
}
|
10
proto/HomeSceneInitFinishRsp.proto
Normal file
10
proto/HomeSceneInitFinishRsp.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4592
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message HomeSceneInitFinishRsp {
|
||||||
|
int32 retcode = 7;
|
||||||
|
}
|
11
proto/HomeSceneJumpReq.proto
Normal file
11
proto/HomeSceneJumpReq.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4659
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message HomeSceneJumpReq {
|
||||||
|
bool is_enter_room_scene = 12;
|
||||||
|
}
|
11
proto/HomeSceneJumpRsp.proto
Normal file
11
proto/HomeSceneJumpRsp.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4570
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message HomeSceneJumpRsp {
|
||||||
|
int32 retcode = 10;
|
||||||
|
bool is_enter_room_scene = 8;
|
||||||
|
}
|
7
proto/HomeUnknown1Notify.proto
Normal file
7
proto/HomeUnknown1Notify.proto
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
message HomeUnknown1Notify {
|
||||||
|
bool is_enter_edit_mode = 12;
|
||||||
|
}
|
13
proto/HomeUpdateArrangementInfoReq.proto
Normal file
13
proto/HomeUpdateArrangementInfoReq.proto
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "HomeSceneArrangementInfo.proto";
|
||||||
|
|
||||||
|
// CmdId: 4472
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message HomeUpdateArrangementInfoReq {
|
||||||
|
HomeSceneArrangementInfo scene_arrangement_info = 12;
|
||||||
|
}
|
10
proto/HomeUpdateArrangementInfoRsp.proto
Normal file
10
proto/HomeUpdateArrangementInfoRsp.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4822
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message HomeUpdateArrangementInfoRsp {
|
||||||
|
int32 retcode = 1;
|
||||||
|
}
|
31
proto/InvestigationMonster.proto
Normal file
31
proto/InvestigationMonster.proto
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "Vector.proto";
|
||||||
|
import "WeeklyBossResinDiscountInfo.proto";
|
||||||
|
|
||||||
|
message InvestigationMonster {
|
||||||
|
enum LockState {
|
||||||
|
LOCK_NONE = 0;
|
||||||
|
LOCK_QUEST = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 id = 1;
|
||||||
|
uint32 city_id = 2;
|
||||||
|
uint32 level = 3;
|
||||||
|
bool is_alive = 4;
|
||||||
|
uint32 next_refresh_time = 5;
|
||||||
|
uint32 refresh_interval = 6;
|
||||||
|
Vector pos = 7;
|
||||||
|
LockState lock_state = 8;
|
||||||
|
uint32 max_boss_chest_num = 9;
|
||||||
|
uint32 boss_chest_num = 10;
|
||||||
|
uint32 resin = 11;
|
||||||
|
bool is_area_locked = 12;
|
||||||
|
uint32 next_boss_chest_refresh_time = 13;
|
||||||
|
WeeklyBossResinDiscountInfo weekly_boss_resin_discount_info = 14;
|
||||||
|
uint32 scene_id = 15;
|
||||||
|
uint32 group_id = 16;
|
||||||
|
uint32 monster_id = 17;
|
||||||
|
}
|
13
proto/TakeFurnitureMakeReq.proto
Normal file
13
proto/TakeFurnitureMakeReq.proto
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4768
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
// IsAllowClient: true
|
||||||
|
message TakeFurnitureMakeReq {
|
||||||
|
uint32 index = 9;
|
||||||
|
uint32 make_id = 4;
|
||||||
|
bool is_fast_finish = 2;
|
||||||
|
}
|
17
proto/TakeFurnitureMakeRsp.proto
Normal file
17
proto/TakeFurnitureMakeRsp.proto
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
import "FurnitureMakeSlot.proto";
|
||||||
|
import "ItemParam.proto";
|
||||||
|
|
||||||
|
// CmdId: 4599
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message TakeFurnitureMakeRsp {
|
||||||
|
int32 retcode = 9;
|
||||||
|
uint32 make_id = 2;
|
||||||
|
FurnitureMakeSlot furniture_make_slot = 15;
|
||||||
|
repeated ItemParam output_item_list = 10;
|
||||||
|
repeated ItemParam return_item_list = 5;
|
||||||
|
}
|
11
proto/UnlockedFurnitureFormulaDataNotify.proto
Normal file
11
proto/UnlockedFurnitureFormulaDataNotify.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4680
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message UnlockedFurnitureFormulaDataNotify {
|
||||||
|
bool is_all = 14;
|
||||||
|
repeated uint32 furniture_id_list = 7;
|
||||||
|
}
|
11
proto/UnlockedFurnitureSuiteDataNotify.proto
Normal file
11
proto/UnlockedFurnitureSuiteDataNotify.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option java_package = "emu.grasscutter.net.proto";
|
||||||
|
|
||||||
|
// CmdId: 4717
|
||||||
|
// EnetChannelId: 0
|
||||||
|
// EnetIsReliable: true
|
||||||
|
message UnlockedFurnitureSuiteDataNotify {
|
||||||
|
bool is_all = 10;
|
||||||
|
repeated uint32 furniture_suite_id_list = 15;
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
package emu.grasscutter.command.commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.command.Command;
|
||||||
|
import emu.grasscutter.command.CommandHandler;
|
||||||
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
|
import emu.grasscutter.game.Account;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
|
||||||
|
import static emu.grasscutter.utils.Language.translate;
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
label = "ban",
|
||||||
|
usage = "ban <player> [time] [reason]",
|
||||||
|
description = "commands.ban.description",
|
||||||
|
targetRequirement = Command.TargetRequirement.NONE
|
||||||
|
)
|
||||||
|
public final class BanCommand implements CommandHandler {
|
||||||
|
|
||||||
|
private boolean banAccount(int uid, int time, String reason) {
|
||||||
|
Player player = Grasscutter.getGameServer().getPlayerByUid(uid, true);
|
||||||
|
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Account account = player.getAccount();
|
||||||
|
if (account == null) {
|
||||||
|
account = DatabaseHelper.getAccountByPlayerId(uid);
|
||||||
|
if (account == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
account.setBanReason(reason);
|
||||||
|
account.setBanEndTime(time);
|
||||||
|
account.setBanStartTime((int) System.currentTimeMillis() / 1000);
|
||||||
|
account.setBanned(true);
|
||||||
|
account.save();
|
||||||
|
|
||||||
|
Player banUser = Grasscutter.getGameServer().getPlayerByUid(uid);
|
||||||
|
|
||||||
|
if (banUser != null) {
|
||||||
|
banUser.getSession().close();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||||
|
if (args.size() < 1) {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.ban.command_usage"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uid = 0;
|
||||||
|
int time = 2051190000;
|
||||||
|
String reason = "Reason not specified.";
|
||||||
|
|
||||||
|
if (args.size() >= 1) {
|
||||||
|
try {
|
||||||
|
uid = Integer.parseInt(args.get(0));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.ban.invalid_player_id"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.size() >= 2) {
|
||||||
|
try {
|
||||||
|
time = Integer.parseInt(args.get(1));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.ban.invalid_time"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.size() >= 3) {
|
||||||
|
reason = args.get(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (banAccount(uid, time, reason)) {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.ban.success"));
|
||||||
|
} else {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.ban.failure"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package emu.grasscutter.command.commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.command.Command;
|
||||||
|
import emu.grasscutter.command.CommandHandler;
|
||||||
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
|
import emu.grasscutter.game.Account;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
|
||||||
|
import static emu.grasscutter.utils.Language.translate;
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
label = "unban",
|
||||||
|
usage = "unban <player>",
|
||||||
|
description = "commands.unban.description",
|
||||||
|
targetRequirement = Command.TargetRequirement.NONE
|
||||||
|
)
|
||||||
|
public final class UnBanCommand implements CommandHandler {
|
||||||
|
|
||||||
|
private boolean unBanAccount(int uid) {
|
||||||
|
Player player = Grasscutter.getGameServer().getPlayerByUid(uid, true);
|
||||||
|
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Account account = player.getAccount();
|
||||||
|
|
||||||
|
if (account == null) {
|
||||||
|
account = DatabaseHelper.getAccountByPlayerId(uid);
|
||||||
|
if (account == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
account.setBanReason(null);
|
||||||
|
account.setBanEndTime(0);
|
||||||
|
account.setBanStartTime(0);
|
||||||
|
account.setBanned(false);
|
||||||
|
account.save();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||||
|
if (args.size() < 1) {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.unban.command_usage"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uid = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
uid = Integer.parseInt(args.get(0));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.unban.invalid_player_id"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unBanAccount(uid)) {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.unban.success"));
|
||||||
|
} else {
|
||||||
|
CommandHandler.sendMessage(sender, translate(sender, "commands.unban.failure"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.binout.*;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
import emu.grasscutter.data.binout.AbilityEmbryoEntry;
|
|
||||||
import emu.grasscutter.data.binout.AbilityModifierEntry;
|
|
||||||
import emu.grasscutter.data.binout.MainQuestData;
|
|
||||||
import emu.grasscutter.data.binout.OpenConfigEntry;
|
|
||||||
import emu.grasscutter.data.binout.ScenePointEntry;
|
|
||||||
import emu.grasscutter.data.excels.*;
|
import emu.grasscutter.data.excels.*;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
@ -28,6 +24,8 @@ public class GameData {
|
|||||||
private static final Map<String, OpenConfigEntry> openConfigEntries = new HashMap<>();
|
private static final Map<String, OpenConfigEntry> openConfigEntries = new HashMap<>();
|
||||||
private static final Map<String, ScenePointEntry> scenePointEntries = new HashMap<>();
|
private static final Map<String, ScenePointEntry> scenePointEntries = new HashMap<>();
|
||||||
private static final Int2ObjectMap<MainQuestData> mainQuestData = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<MainQuestData> mainQuestData = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<HomeworldDefaultSaveData> homeworldDefaultSaveData = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<SceneNpcBornData> npcBornData = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
// ExcelConfigs
|
// ExcelConfigs
|
||||||
private static final Int2ObjectMap<PlayerLevelData> playerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<PlayerLevelData> playerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
@ -80,15 +78,21 @@ public class GameData {
|
|||||||
private static final Int2ObjectMap<WorldAreaData> worldAreaDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<WorldAreaData> worldAreaDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<DungeonEntryData> dungeonEntryDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<QuestData> questDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<QuestData> questDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
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<GatherData> gatherDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<TowerLevelData> towerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<TowerLevelData> towerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<TowerScheduleData> towerScheduleDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<TowerScheduleData> towerScheduleDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<ForgeData> forgeDataMap = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<ForgeData> forgeDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<HomeWorldLevelData> homeWorldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<FurnitureMakeConfigData> furnitureMakeConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||||
@ -141,6 +145,14 @@ public class GameData {
|
|||||||
return mainQuestData;
|
return mainQuestData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<HomeworldDefaultSaveData> getHomeworldDefaultSaveData() {
|
||||||
|
return homeworldDefaultSaveData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<SceneNpcBornData> getSceneNpcBornData() {
|
||||||
|
return npcBornData;
|
||||||
|
}
|
||||||
|
|
||||||
public static Int2ObjectMap<AvatarData> getAvatarDataMap() {
|
public static Int2ObjectMap<AvatarData> getAvatarDataMap() {
|
||||||
return avatarDataMap;
|
return avatarDataMap;
|
||||||
}
|
}
|
||||||
@ -336,6 +348,10 @@ public class GameData {
|
|||||||
return dailyDungeonDataMap;
|
return dailyDungeonDataMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<DungeonEntryData> getDungeonEntryDatatMap(){
|
||||||
|
return dungeonEntryDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
public static Map<Integer, List<ShopGoodsData>> getShopGoodsDataEntries() {
|
public static Map<Integer, List<ShopGoodsData>> getShopGoodsDataEntries() {
|
||||||
if (shopGoods.isEmpty()) {
|
if (shopGoods.isEmpty()) {
|
||||||
shopGoodsDataMap.forEach((k, v) -> {
|
shopGoodsDataMap.forEach((k, v) -> {
|
||||||
@ -363,9 +379,11 @@ public class GameData {
|
|||||||
public static Int2ObjectMap<TowerFloorData> getTowerFloorDataMap(){
|
public static Int2ObjectMap<TowerFloorData> getTowerFloorDataMap(){
|
||||||
return towerFloorDataMap;
|
return towerFloorDataMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int2ObjectMap<TowerLevelData> getTowerLevelDataMap(){
|
public static Int2ObjectMap<TowerLevelData> getTowerLevelDataMap(){
|
||||||
return towerLevelDataMap;
|
return towerLevelDataMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int2ObjectMap<TowerScheduleData> getTowerScheduleDataMap(){
|
public static Int2ObjectMap<TowerScheduleData> getTowerScheduleDataMap(){
|
||||||
return towerScheduleDataMap;
|
return towerScheduleDataMap;
|
||||||
}
|
}
|
||||||
@ -377,4 +395,20 @@ public class GameData {
|
|||||||
public static Int2ObjectMap<ForgeData> getForgeDataMap() {
|
public static Int2ObjectMap<ForgeData> getForgeDataMap() {
|
||||||
return forgeDataMap;
|
return forgeDataMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<HomeWorldLevelData> getHomeWorldLevelDataMap() {
|
||||||
|
return homeWorldLevelDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<FurnitureMakeConfigData> getFurnitureMakeConfigDataMap() {
|
||||||
|
return furnitureMakeConfigDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<GatherData> getGatherDataMap() {
|
||||||
|
return gatherDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Int2ObjectMap<InvestigationMonsterData> getInvestigationMonsterDataMap() {
|
||||||
|
return investigationMonsterDataMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
package emu.grasscutter.data;
|
package emu.grasscutter.data;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import emu.grasscutter.data.binout.*;
|
||||||
|
import emu.grasscutter.scripts.SceneIndexManager;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
@ -15,12 +20,6 @@ import com.google.gson.annotations.SerializedName;
|
|||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.binout.AbilityEmbryoEntry;
|
|
||||||
import emu.grasscutter.data.binout.AbilityModifier;
|
|
||||||
import emu.grasscutter.data.binout.AbilityModifierEntry;
|
|
||||||
import emu.grasscutter.data.binout.MainQuestData;
|
|
||||||
import emu.grasscutter.data.binout.OpenConfigEntry;
|
|
||||||
import emu.grasscutter.data.binout.ScenePointEntry;
|
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType;
|
||||||
@ -66,6 +65,9 @@ public class ResourceLoader {
|
|||||||
loadQuests();
|
loadQuests();
|
||||||
// Load scene points - must be done AFTER resources are loaded
|
// Load scene points - must be done AFTER resources are loaded
|
||||||
loadScenePoints();
|
loadScenePoints();
|
||||||
|
// Load default home layout
|
||||||
|
loadHomeworldDefaultSaveData();
|
||||||
|
loadNpcBornData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadResources() {
|
public static void loadResources() {
|
||||||
@ -394,6 +396,47 @@ public class ResourceLoader {
|
|||||||
Grasscutter.getLogger().info("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
|
Grasscutter.getLogger().info("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private static void loadHomeworldDefaultSaveData(){
|
||||||
|
var folder = Files.list(Path.of(RESOURCE("BinOutput/HomeworldDefaultSave"))).toList();
|
||||||
|
var pattern = Pattern.compile("scene(.*)_home_config.json");
|
||||||
|
|
||||||
|
for(var file : folder){
|
||||||
|
var matcher = pattern.matcher(file.getFileName().toString());
|
||||||
|
if(!matcher.find()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var sceneId = matcher.group(1);
|
||||||
|
|
||||||
|
var data = Grasscutter.getGsonFactory().fromJson(Files.readString(file), HomeworldDefaultSaveData.class);
|
||||||
|
|
||||||
|
GameData.getHomeworldDefaultSaveData().put(Integer.parseInt(sceneId), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Grasscutter.getLogger().info("Loaded " + GameData.getHomeworldDefaultSaveData().size() + " HomeworldDefaultSaveDatas.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private static void loadNpcBornData(){
|
||||||
|
var folder = Files.list(Path.of(RESOURCE("BinOutput/Scene/SceneNpcBorn"))).toList();
|
||||||
|
|
||||||
|
for(var file : folder){
|
||||||
|
if(file.toFile().isDirectory()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = Grasscutter.getGsonFactory().fromJson(Files.readString(file), SceneNpcBornData.class);
|
||||||
|
if(data.getBornPosList() == null || data.getBornPosList().size() == 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.setIndex(SceneIndexManager.buildIndex(3, data.getBornPosList(), item -> item.getPos().toPoint()));
|
||||||
|
GameData.getSceneNpcBornData().put(data.getSceneId(), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Grasscutter.getLogger().info("Loaded " + GameData.getSceneNpcBornData().size() + " SceneNpcBornDatas.");
|
||||||
|
}
|
||||||
|
|
||||||
// BinOutput configs
|
// BinOutput configs
|
||||||
|
|
||||||
public static class AvatarConfig {
|
public static class AvatarConfig {
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package emu.grasscutter.data.binout;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
public class HomeworldDefaultSaveData {
|
||||||
|
|
||||||
|
@SerializedName(value = "KFHBFNPDJBE", alternate = "PKACPHDGGEI")
|
||||||
|
List<HomeBlock> homeBlockLists;
|
||||||
|
@SerializedName(value = "IJNPADKGNKE", alternate = "MINCKHBNING")
|
||||||
|
Position bornPos;
|
||||||
|
@SerializedName("IPIIGEMFLHK")
|
||||||
|
Position bornRot;
|
||||||
|
@SerializedName("HHOLBNPIHEM")
|
||||||
|
Position djinPos;
|
||||||
|
@SerializedName("KNHCJKHCOAN")
|
||||||
|
HomeFurniture mainhouse;
|
||||||
|
|
||||||
|
@SerializedName("NIHOJFEKFPG")
|
||||||
|
List<HomeFurniture> doorLists;
|
||||||
|
@SerializedName("EPGELGEFJFK")
|
||||||
|
List<HomeFurniture> stairLists;
|
||||||
|
@Data
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
public static class HomeBlock{
|
||||||
|
|
||||||
|
@SerializedName(value = "FGIJCELCGFI", alternate = "PGDPDIDJEEL")
|
||||||
|
int blockId;
|
||||||
|
|
||||||
|
@SerializedName(value = "BEAPOFELABD", alternate = "MLIODLGDFHJ")
|
||||||
|
List<HomeFurniture> furnitures;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
public static class HomeFurniture{
|
||||||
|
|
||||||
|
@SerializedName(value = "ENHNGKJBJAB", alternate = "KMAAJJHPNBA")
|
||||||
|
int id;
|
||||||
|
@SerializedName(value = "NGIEEIOLPPO", alternate = "JFKAHNCPDME")
|
||||||
|
Position pos;
|
||||||
|
//@SerializedName(value = "HEOCEHKEBFM", alternate = "LKCKOOGFDBM")
|
||||||
|
Position rot;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package emu.grasscutter.data.binout;
|
||||||
|
|
||||||
|
import com.github.davidmoten.rtreemulti.RTree;
|
||||||
|
import com.github.davidmoten.rtreemulti.geometry.Geometry;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
public class SceneNpcBornData {
|
||||||
|
int sceneId;
|
||||||
|
List<SceneNpcBornEntry> bornPosList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spatial Index For NPC
|
||||||
|
*/
|
||||||
|
transient RTree<SceneNpcBornEntry, Geometry> index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* npc groups
|
||||||
|
*/
|
||||||
|
transient Map<Integer, SceneGroup> groups = new ConcurrentHashMap<>();
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package emu.grasscutter.data.binout;
|
||||||
|
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
public class SceneNpcBornEntry {
|
||||||
|
@SerializedName(value="id", alternate={"_id", "ID"})
|
||||||
|
int id;
|
||||||
|
|
||||||
|
@SerializedName(value="configId", alternate={"_configId"})
|
||||||
|
int configId;
|
||||||
|
|
||||||
|
@SerializedName(value="pos", alternate={"_pos"})
|
||||||
|
Position pos;
|
||||||
|
|
||||||
|
@SerializedName(value="rot", alternate={"_rot"})
|
||||||
|
Position rot;
|
||||||
|
|
||||||
|
@SerializedName(value="groupId", alternate={"_groupId"})
|
||||||
|
int groupId;
|
||||||
|
|
||||||
|
@SerializedName(value="suiteIdList", alternate={"_suiteIdList"})
|
||||||
|
List<Integer> suiteIdList;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@ResourceType(name = "DungeonEntryExcelConfigData.json")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class DungeonEntryData extends GameResource {
|
||||||
|
private int dungeonEntryId;
|
||||||
|
private int sceneId;
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
@ResourceType(name = {"FurnitureMakeExcelConfigData.json"})
|
||||||
|
public class FurnitureMakeConfigData extends GameResource {
|
||||||
|
|
||||||
|
int configID;
|
||||||
|
int furnitureItemID;
|
||||||
|
int count;
|
||||||
|
int exp;
|
||||||
|
List<ItemParamData> materialItems;
|
||||||
|
int makeTime;
|
||||||
|
int maxAccelerateTime;
|
||||||
|
int quickFetchMaterialNum;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return configID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
this.materialItems = materialItems.stream()
|
||||||
|
.filter(x -> x.getId() > 0)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
49
src/main/java/emu/grasscutter/data/excels/GatherData.java
Normal file
49
src/main/java/emu/grasscutter/data/excels/GatherData.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
|
||||||
|
@ResourceType(name = "GatherExcelConfigData.json")
|
||||||
|
public class GatherData extends GameResource {
|
||||||
|
private int pointType;
|
||||||
|
private int id;
|
||||||
|
private int gadgetId;
|
||||||
|
private int itemId;
|
||||||
|
private int cd; // Probably hours
|
||||||
|
private boolean isForbidGuest;
|
||||||
|
private boolean initDisableInteract;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return this.pointType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGatherId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGadgetId() {
|
||||||
|
return gadgetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getItemId() {
|
||||||
|
return itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCd() {
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForbidGuest() {
|
||||||
|
return isForbidGuest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean initDisableInteract() {
|
||||||
|
return initDisableInteract;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
@ResourceType(name = {"HomeworldLevelExcelConfigData.json"})
|
||||||
|
public class HomeWorldLevelData extends GameResource {
|
||||||
|
|
||||||
|
int level;
|
||||||
|
int exp;
|
||||||
|
int homeCoinStoreLimit;
|
||||||
|
int homeFetterExpStoreLimit;
|
||||||
|
int rewardId;
|
||||||
|
int furnitureMakeSlotCount;
|
||||||
|
int outdoorUnlockBlockCount;
|
||||||
|
int freeUnlockModuleCount;
|
||||||
|
int deployNpcCount;
|
||||||
|
int limitShopGoodsCount;
|
||||||
|
List<String> levelFuncs;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
super.onLoad();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameResource;
|
||||||
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@ResourceType(name = "InvestigationMonsterConfigData.json")
|
||||||
|
@Data
|
||||||
|
public class InvestigationMonsterData extends GameResource {
|
||||||
|
private int id;
|
||||||
|
private int cityId;
|
||||||
|
private List<Integer> monsterIdList;
|
||||||
|
private List<Integer> groupIdList;
|
||||||
|
private int rewardPreviewId;
|
||||||
|
private String mapMarkCreateType;
|
||||||
|
private String monsterCategory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
super.onLoad();
|
||||||
|
}
|
||||||
|
}
|
@ -2,14 +2,20 @@ package emu.grasscutter.data.excels;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import emu.grasscutter.data.common.ItemUseData;
|
import emu.grasscutter.data.common.ItemUseData;
|
||||||
|
import emu.grasscutter.game.inventory.*;
|
||||||
import emu.grasscutter.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
|
||||||
@ResourceType(name = {"MaterialExcelConfigData.json", "WeaponExcelConfigData.json", "ReliquaryExcelConfigData.json"})
|
@ResourceType(name = {"MaterialExcelConfigData.json",
|
||||||
|
"WeaponExcelConfigData.json",
|
||||||
|
"ReliquaryExcelConfigData.json",
|
||||||
|
"HomeWorldFurnitureExcelConfigData.json"
|
||||||
|
})
|
||||||
public class ItemData extends GameResource {
|
public class ItemData extends GameResource {
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
@ -63,12 +69,19 @@ public class ItemData extends GameResource {
|
|||||||
private long nameTextMapHash;
|
private long nameTextMapHash;
|
||||||
|
|
||||||
// Post load
|
// Post load
|
||||||
private transient emu.grasscutter.game.inventory.MaterialType materialEnumType;
|
private transient MaterialType materialEnumType;
|
||||||
private transient emu.grasscutter.game.inventory.ItemType itemEnumType;
|
private transient ItemType itemEnumType;
|
||||||
private transient emu.grasscutter.game.inventory.EquipType equipEnumType;
|
private transient EquipType equipEnumType;
|
||||||
|
|
||||||
private IntSet addPropLevelSet;
|
private IntSet addPropLevelSet;
|
||||||
|
|
||||||
|
// Furniture
|
||||||
|
private int comfort;
|
||||||
|
private List<Integer> furnType;
|
||||||
|
private List<Integer> furnitureGadgetID;
|
||||||
|
@SerializedName("JFDLJGDFIGL")
|
||||||
|
private int roomSceneId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId(){
|
public int getId(){
|
||||||
return this.id;
|
return this.id;
|
||||||
@ -194,40 +207,56 @@ public class ItemData extends GameResource {
|
|||||||
return maxLevel;
|
return maxLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public emu.grasscutter.game.inventory.ItemType getItemType() {
|
public int getComfort() {
|
||||||
|
return comfort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getFurnType() {
|
||||||
|
return furnType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getFurnitureGadgetID() {
|
||||||
|
return furnitureGadgetID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRoomSceneId() {
|
||||||
|
return roomSceneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemType getItemType() {
|
||||||
return this.itemEnumType;
|
return this.itemEnumType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public emu.grasscutter.game.inventory.MaterialType getMaterialType() {
|
public MaterialType getMaterialType() {
|
||||||
return this.materialEnumType;
|
return this.materialEnumType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public emu.grasscutter.game.inventory.EquipType getEquipType() {
|
public EquipType getEquipType() {
|
||||||
return this.equipEnumType;
|
return this.equipEnumType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canAddRelicProp(int level) {
|
public boolean canAddRelicProp(int level) {
|
||||||
return this.addPropLevelSet != null & this.addPropLevelSet.contains(level);
|
return this.addPropLevelSet != null && this.addPropLevelSet.contains(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEquip() {
|
public boolean isEquip() {
|
||||||
return this.itemEnumType == emu.grasscutter.game.inventory.ItemType.ITEM_RELIQUARY || this.itemEnumType == emu.grasscutter.game.inventory.ItemType.ITEM_WEAPON;
|
return this.itemEnumType == ItemType.ITEM_RELIQUARY || this.itemEnumType == ItemType.ITEM_WEAPON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
this.itemEnumType = emu.grasscutter.game.inventory.ItemType.getTypeByName(getItemTypeString());
|
this.itemEnumType = ItemType.getTypeByName(getItemTypeString());
|
||||||
this.materialEnumType = emu.grasscutter.game.inventory.MaterialType.getTypeByName(getMaterialTypeString());
|
this.materialEnumType = MaterialType.getTypeByName(getMaterialTypeString());
|
||||||
|
|
||||||
if (this.itemEnumType == emu.grasscutter.game.inventory.ItemType.ITEM_RELIQUARY) {
|
if (this.itemEnumType == ItemType.ITEM_RELIQUARY) {
|
||||||
this.equipEnumType = emu.grasscutter.game.inventory.EquipType.getTypeByName(this.equipType);
|
this.equipEnumType = EquipType.getTypeByName(this.equipType);
|
||||||
if (this.addPropLevels != null && this.addPropLevels.length > 0) {
|
if (this.addPropLevels != null && this.addPropLevels.length > 0) {
|
||||||
this.addPropLevelSet = new IntOpenHashSet(this.addPropLevels);
|
this.addPropLevelSet = new IntOpenHashSet(this.addPropLevels);
|
||||||
}
|
}
|
||||||
} else if (this.itemEnumType == emu.grasscutter.game.inventory.ItemType.ITEM_WEAPON) {
|
} else if (this.itemEnumType == ItemType.ITEM_WEAPON) {
|
||||||
this.equipEnumType = emu.grasscutter.game.inventory.EquipType.EQUIP_WEAPON;
|
this.equipEnumType = EquipType.EQUIP_WEAPON;
|
||||||
} else {
|
} else {
|
||||||
this.equipEnumType = emu.grasscutter.game.inventory.EquipType.EQUIP_NONE;
|
this.equipEnumType = EquipType.EQUIP_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getWeaponProperties() != null) {
|
if (this.getWeaponProperties() != null) {
|
||||||
@ -235,6 +264,13 @@ public class ItemData extends GameResource {
|
|||||||
weaponProperty.onLoad();
|
weaponProperty.onLoad();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.getFurnType() != null){
|
||||||
|
this.furnType = this.furnType.stream().filter(x -> x > 0).toList();
|
||||||
|
}
|
||||||
|
if(this.getFurnitureGadgetID() != null){
|
||||||
|
this.furnitureGadgetID = this.furnitureGadgetID.stream().filter(x -> x > 0).toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WeaponProperty {
|
public static class WeaponProperty {
|
||||||
|
@ -13,6 +13,7 @@ import emu.grasscutter.game.Account;
|
|||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.friends.Friendship;
|
import emu.grasscutter.game.friends.Friendship;
|
||||||
import emu.grasscutter.game.gacha.GachaRecord;
|
import emu.grasscutter.game.gacha.GachaRecord;
|
||||||
|
import emu.grasscutter.game.home.GameHome;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
import emu.grasscutter.game.mail.Mail;
|
import emu.grasscutter.game.mail.Mail;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
@ -295,4 +296,10 @@ public final class DatabaseHelper {
|
|||||||
public static boolean deleteQuest(GameMainQuest quest) {
|
public static boolean deleteQuest(GameMainQuest quest) {
|
||||||
return DatabaseManager.getGameDatastore().delete(quest).wasAcknowledged();
|
return DatabaseManager.getGameDatastore().delete(quest).wasAcknowledged();
|
||||||
}
|
}
|
||||||
|
public static GameHome getHomeByUid(int id) {
|
||||||
|
return DatabaseManager.getGameDatastore().find(GameHome.class).filter(Filters.eq("ownerUid", id)).first();
|
||||||
|
}
|
||||||
|
public static void saveHome(GameHome gameHome) {
|
||||||
|
DatabaseManager.getGameDatastore().save(gameHome);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import emu.grasscutter.game.Account;
|
|||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.friends.Friendship;
|
import emu.grasscutter.game.friends.Friendship;
|
||||||
import emu.grasscutter.game.gacha.GachaRecord;
|
import emu.grasscutter.game.gacha.GachaRecord;
|
||||||
|
import emu.grasscutter.game.home.GameHome;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
import emu.grasscutter.game.mail.Mail;
|
import emu.grasscutter.game.mail.Mail;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
@ -30,7 +31,7 @@ public final class DatabaseManager {
|
|||||||
|
|
||||||
private static final Class<?>[] mappedClasses = new Class<?>[] {
|
private static final Class<?>[] mappedClasses = new Class<?>[] {
|
||||||
DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class,
|
DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class,
|
||||||
GachaRecord.class, Mail.class, GameMainQuest.class
|
GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Datastore getGameDatastore() {
|
public static Datastore getGameDatastore() {
|
||||||
|
@ -29,6 +29,11 @@ public class Account {
|
|||||||
private List<String> permissions;
|
private List<String> permissions;
|
||||||
private Locale locale;
|
private Locale locale;
|
||||||
|
|
||||||
|
private String banReason;
|
||||||
|
private int banEndTime;
|
||||||
|
private int banStartTime;
|
||||||
|
private boolean isBanned;
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Account() {
|
public Account() {
|
||||||
this.permissions = new ArrayList<>();
|
this.permissions = new ArrayList<>();
|
||||||
@ -105,6 +110,46 @@ public class Account {
|
|||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getBanReason() {
|
||||||
|
return banReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBanReason(String banReason) {
|
||||||
|
this.banReason = banReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBanEndTime() {
|
||||||
|
return banEndTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBanEndTime(int banEndTime) {
|
||||||
|
this.banEndTime = banEndTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBanStartTime() {
|
||||||
|
return banStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBanStartTime(int banStartTime) {
|
||||||
|
this.banStartTime = banStartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBanned() {
|
||||||
|
if (banEndTime > 0 && banEndTime < System.currentTimeMillis() / 1000) {
|
||||||
|
this.isBanned = false;
|
||||||
|
this.banEndTime = 0;
|
||||||
|
this.banStartTime = 0;
|
||||||
|
this.banReason = null;
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return isBanned;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBanned(boolean isBanned) {
|
||||||
|
this.isBanned = isBanned;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The collection of a player's permissions.
|
* The collection of a player's permissions.
|
||||||
*/
|
*/
|
||||||
|
@ -1,223 +0,0 @@
|
|||||||
package emu.grasscutter.game.dungeons;
|
|
||||||
|
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
|
||||||
import emu.grasscutter.data.excels.DungeonData;
|
|
||||||
import emu.grasscutter.game.entity.EntityMonster;
|
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
|
||||||
import emu.grasscutter.game.inventory.ItemType;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
|
||||||
import emu.grasscutter.game.props.ActionReason;
|
|
||||||
import emu.grasscutter.game.world.Scene;
|
|
||||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
|
||||||
import emu.grasscutter.scripts.constants.EventType;
|
|
||||||
import emu.grasscutter.scripts.data.SceneGroup;
|
|
||||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketGadgetAutoPickDropInfoNotify;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class DungeonChallenge {
|
|
||||||
private final Scene scene;
|
|
||||||
private final SceneGroup group;
|
|
||||||
|
|
||||||
private int challengeIndex;
|
|
||||||
private int challengeId;
|
|
||||||
private boolean success;
|
|
||||||
private boolean progress;
|
|
||||||
/**
|
|
||||||
* has more challenge
|
|
||||||
*/
|
|
||||||
private boolean stage;
|
|
||||||
private int score;
|
|
||||||
private int objective = 0;
|
|
||||||
private IntSet rewardedPlayers;
|
|
||||||
|
|
||||||
public DungeonChallenge(Scene scene, SceneGroup group, int challengeId, int challengeIndex, int objective) {
|
|
||||||
this.scene = scene;
|
|
||||||
this.group = group;
|
|
||||||
this.challengeId = challengeId;
|
|
||||||
this.challengeIndex = challengeIndex;
|
|
||||||
this.objective = objective;
|
|
||||||
this.setRewardedPlayers(new IntOpenHashSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Scene getScene() {
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SceneGroup getGroup() {
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChallengeIndex() {
|
|
||||||
return challengeIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChallengeIndex(int challengeIndex) {
|
|
||||||
this.challengeIndex = challengeIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChallengeId() {
|
|
||||||
return challengeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChallengeId(int challengeId) {
|
|
||||||
this.challengeId = challengeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getObjective() {
|
|
||||||
return objective;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObjective(int objective) {
|
|
||||||
this.objective = objective;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSuccess() {
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSuccess(boolean isSuccess) {
|
|
||||||
this.success = isSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean inProgress() {
|
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getScore() {
|
|
||||||
return score;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStage() {
|
|
||||||
return stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStage(boolean stage) {
|
|
||||||
this.stage = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTimeLimit() {
|
|
||||||
return 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntSet getRewardedPlayers() {
|
|
||||||
return rewardedPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRewardedPlayers(IntSet rewardedPlayers) {
|
|
||||||
this.rewardedPlayers = rewardedPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
|
||||||
this.progress = true;
|
|
||||||
getScene().broadcastPacket(new PacketDungeonChallengeBeginNotify(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void finish() {
|
|
||||||
this.progress = false;
|
|
||||||
|
|
||||||
getScene().broadcastPacket(new PacketDungeonChallengeFinishNotify(this));
|
|
||||||
|
|
||||||
if (this.isSuccess()) {
|
|
||||||
// Call success script event
|
|
||||||
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS, null);
|
|
||||||
|
|
||||||
// Settle
|
|
||||||
settle();
|
|
||||||
} else {
|
|
||||||
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_FAIL, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void settle() {
|
|
||||||
getScene().getDungeonSettleObservers().forEach(o -> o.onDungeonSettle(getScene()));
|
|
||||||
|
|
||||||
if(!stage){
|
|
||||||
getScene().getScriptManager().callEvent(EventType.EVENT_DUNGEON_SETTLE, new ScriptArgs(this.isSuccess() ? 1 : 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onMonsterDie(EntityMonster entity) {
|
|
||||||
score = getScore() + 1;
|
|
||||||
|
|
||||||
getScene().broadcastPacket(new PacketChallengeDataNotify(this, 1, getScore()));
|
|
||||||
|
|
||||||
if (getScore() >= getObjective() && this.progress) {
|
|
||||||
this.setSuccess(true);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<GameItem> rollRewards() {
|
|
||||||
List<GameItem> rewards = new ArrayList<>();
|
|
||||||
|
|
||||||
for (ItemParamData param : getScene().getDungeonData().getRewardPreview().getPreviewItems()) {
|
|
||||||
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rewards;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getStatueDrops(Player player, GadgetInteractReq request) {
|
|
||||||
DungeonData dungeonData = getScene().getDungeonData();
|
|
||||||
int resinCost = dungeonData.getStatueCostCount() != 0 ? dungeonData.getStatueCostCount() : 20;
|
|
||||||
|
|
||||||
if (!isSuccess() || dungeonData == null || dungeonData.getRewardPreview() == null || dungeonData.getRewardPreview().getPreviewItems().length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Already rewarded
|
|
||||||
if (getRewardedPlayers().contains(player.getUid())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rewards.
|
|
||||||
List<GameItem> rewards = new ArrayList<>();
|
|
||||||
|
|
||||||
if (request.getIsUseCondenseResin()) {
|
|
||||||
// Check if condensed resin is usable here.
|
|
||||||
// For this, we use the following logic for now:
|
|
||||||
// The normal resin cost of the dungeon has to be 20.
|
|
||||||
if (resinCost != 20) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the player has condensed resin.
|
|
||||||
GameItem condensedResin = player.getInventory().getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(220007);
|
|
||||||
if (condensedResin == null || condensedResin.getCount() <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deduct.
|
|
||||||
player.getInventory().removeItem(condensedResin, 1);
|
|
||||||
|
|
||||||
// Roll rewards, twice (because condensed).
|
|
||||||
rewards.addAll(this.rollRewards());
|
|
||||||
rewards.addAll(this.rollRewards());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// If the player used regular resin, try to deduct.
|
|
||||||
// Stop if insufficient resin.
|
|
||||||
boolean success = player.getResinManager().useResin(resinCost);
|
|
||||||
if (!success) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Roll rewards.
|
|
||||||
rewards.addAll(this.rollRewards());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add rewards to player and send notification.
|
|
||||||
player.getInventory().addItems(rewards, ActionReason.DungeonStatueDrop);
|
|
||||||
player.sendPacket(new PacketGadgetAutoPickDropInfoNotify(rewards));
|
|
||||||
|
|
||||||
getRewardedPlayers().add(player.getUid());
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,91 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
|
import emu.grasscutter.data.excels.DungeonData;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.ChallengeTrigger;
|
||||||
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketGadgetAutoPickDropInfoNotify;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DungeonChallenge extends WorldChallenge {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* has more challenge
|
||||||
|
*/
|
||||||
|
private boolean stage;
|
||||||
|
private IntSet rewardedPlayers;
|
||||||
|
|
||||||
|
public DungeonChallenge(Scene scene, SceneGroup group,
|
||||||
|
int challengeId, int challengeIndex,
|
||||||
|
List<Integer> paramList,
|
||||||
|
int timeLimit, int goal,
|
||||||
|
List<ChallengeTrigger> challengeTriggers) {
|
||||||
|
super(scene, group, challengeId, challengeIndex, paramList, timeLimit, goal, challengeTriggers);
|
||||||
|
this.setRewardedPlayers(new IntOpenHashSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStage() {
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStage(boolean stage) {
|
||||||
|
this.stage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntSet getRewardedPlayers() {
|
||||||
|
return rewardedPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRewardedPlayers(IntSet rewardedPlayers) {
|
||||||
|
this.rewardedPlayers = rewardedPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void done() {
|
||||||
|
super.done();
|
||||||
|
if (this.isSuccess()) {
|
||||||
|
// Settle
|
||||||
|
settle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void settle() {
|
||||||
|
if(!stage){
|
||||||
|
getScene().getDungeonSettleObservers().forEach(o -> o.onDungeonSettle(getScene()));
|
||||||
|
getScene().getScriptManager().callEvent(EventType.EVENT_DUNGEON_SETTLE,
|
||||||
|
new ScriptArgs(this.isSuccess() ? 1 : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getStatueDrops(Player player) {
|
||||||
|
DungeonData dungeonData = getScene().getDungeonData();
|
||||||
|
if (!isSuccess() || dungeonData == null || dungeonData.getRewardPreview() == null || dungeonData.getRewardPreview().getPreviewItems().length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already rewarded
|
||||||
|
if (getRewardedPlayers().contains(player.getUid())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GameItem> rewards = new ArrayList<>();
|
||||||
|
for (ItemParamData param : getScene().getDungeonData().getRewardPreview().getPreviewItems()) {
|
||||||
|
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
player.getInventory().addItems(rewards, ActionReason.DungeonStatueDrop);
|
||||||
|
player.sendPacket(new PacketGadgetAutoPickDropInfoNotify(rewards));
|
||||||
|
|
||||||
|
getRewardedPlayers().add(player.getUid());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.ChallengeTrigger;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class WorldChallenge {
|
||||||
|
private final Scene scene;
|
||||||
|
private final SceneGroup group;
|
||||||
|
private final int challengeId;
|
||||||
|
private final int challengeIndex;
|
||||||
|
private final List<Integer> paramList;
|
||||||
|
private final int timeLimit;
|
||||||
|
private final List<ChallengeTrigger> challengeTriggers;
|
||||||
|
private boolean progress;
|
||||||
|
private boolean success;
|
||||||
|
private long startedAt;
|
||||||
|
private int finishedTime;
|
||||||
|
private final int goal;
|
||||||
|
private final AtomicInteger score;
|
||||||
|
|
||||||
|
public WorldChallenge(Scene scene, SceneGroup group,
|
||||||
|
int challengeId, int challengeIndex, List<Integer> paramList,
|
||||||
|
int timeLimit, int goal,
|
||||||
|
List<ChallengeTrigger> challengeTriggers){
|
||||||
|
this.scene = scene;
|
||||||
|
this.group = group;
|
||||||
|
this.challengeId = challengeId;
|
||||||
|
this.challengeIndex = challengeIndex;
|
||||||
|
this.paramList = paramList;
|
||||||
|
this.timeLimit = timeLimit;
|
||||||
|
this.challengeTriggers = challengeTriggers;
|
||||||
|
this.goal = goal;
|
||||||
|
this.score = new AtomicInteger(0);
|
||||||
|
}
|
||||||
|
public boolean inProgress(){
|
||||||
|
return this.progress;
|
||||||
|
}
|
||||||
|
public void onCheckTimeOut(){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(timeLimit <= 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
challengeTriggers.forEach(t -> t.onCheckTimeout(this));
|
||||||
|
}
|
||||||
|
public void start(){
|
||||||
|
if(inProgress()){
|
||||||
|
Grasscutter.getLogger().info("Could not start a in progress challenge.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.progress = true;
|
||||||
|
this.startedAt = System.currentTimeMillis();
|
||||||
|
getScene().broadcastPacket(new PacketDungeonChallengeBeginNotify(this));
|
||||||
|
challengeTriggers.forEach(t -> t.onBegin(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void done(){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finish(true);
|
||||||
|
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS,
|
||||||
|
// TODO record the time in PARAM2 and used in action
|
||||||
|
new ScriptArgs().setParam2(finishedTime));
|
||||||
|
|
||||||
|
challengeTriggers.forEach(t -> t.onFinish(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fail(){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finish(false);
|
||||||
|
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_FAIL, null);
|
||||||
|
challengeTriggers.forEach(t -> t.onFinish(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finish(boolean success){
|
||||||
|
this.progress = false;
|
||||||
|
this.success = success;
|
||||||
|
this.finishedTime = (int)((System.currentTimeMillis() - this.startedAt) / 1000L);
|
||||||
|
getScene().broadcastPacket(new PacketDungeonChallengeFinishNotify(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int increaseScore(){
|
||||||
|
return score.incrementAndGet();
|
||||||
|
}
|
||||||
|
public void onMonsterDeath(EntityMonster monster){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(monster.getGroupId() != getGroup().id){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.challengeTriggers.forEach(t -> t.onMonsterDeath(this, monster));
|
||||||
|
}
|
||||||
|
public void onGadgetDeath(EntityGadget gadget){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(gadget.getGroupId() != getGroup().id){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.challengeTriggers.forEach(t -> t.onGadgetDeath(this, gadget));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onGadgetDamage(EntityGadget gadget){
|
||||||
|
if(!inProgress()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(gadget.getGroupId() != getGroup().id){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.challengeTriggers.forEach(t -> t.onGadgetDamage(this, gadget));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ChallengeFactory {
|
||||||
|
|
||||||
|
private static final List<ChallengeFactoryHandler> challengeFactoryHandlers = new ArrayList<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
challengeFactoryHandlers.add(new DungeonChallengeFactoryHandler());
|
||||||
|
challengeFactoryHandlers.add(new DungeonGuardChallengeFactoryHandler());
|
||||||
|
challengeFactoryHandlers.add(new KillGadgetChallengeFactoryHandler());
|
||||||
|
challengeFactoryHandlers.add(new KillMonsterChallengeFactoryHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WorldChallenge getChallenge(int param1, int param2, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group){
|
||||||
|
for(var handler : challengeFactoryHandlers){
|
||||||
|
if(!handler.isThisType(param1, param2, param3, param4, param5, param6, scene, group)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return handler.build(param1, param2, param3, param4, param5, param6, scene, group);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
public interface ChallengeFactoryHandler {
|
||||||
|
boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group);
|
||||||
|
WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group);
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.DungeonChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger;
|
||||||
|
import emu.grasscutter.game.props.SceneType;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DungeonChallengeFactoryHandler implements ChallengeFactoryHandler{
|
||||||
|
@Override
|
||||||
|
public boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
// ActiveChallenge with 1,1000,300,233101003,15,0
|
||||||
|
return scene.getSceneType() == SceneType.SCENE_DUNGEON
|
||||||
|
&& param4 == group.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
var realGroup = scene.getScriptManager().getGroupById(param4);
|
||||||
|
return new DungeonChallenge(
|
||||||
|
scene, realGroup,
|
||||||
|
challengeId, // Id
|
||||||
|
challengeIndex, // Index
|
||||||
|
List.of(param5, param3),
|
||||||
|
param3, // Limit
|
||||||
|
param5, // Goal
|
||||||
|
List.of(new InTimeTrigger(), new KillMonsterTrigger()));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.DungeonChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.GuardTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger;
|
||||||
|
import emu.grasscutter.game.props.SceneType;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DungeonGuardChallengeFactoryHandler implements ChallengeFactoryHandler{
|
||||||
|
@Override
|
||||||
|
public boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
// ActiveChallenge with 1,188,234101003,12,3030,0
|
||||||
|
return scene.getSceneType() == SceneType.SCENE_DUNGEON
|
||||||
|
&& param3 == group.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
var realGroup = scene.getScriptManager().getGroupById(param3);
|
||||||
|
return new DungeonChallenge(
|
||||||
|
scene, realGroup,
|
||||||
|
challengeId, // Id
|
||||||
|
challengeIndex, // Index
|
||||||
|
List.of(param4, 0),
|
||||||
|
0, // Limit
|
||||||
|
param5, // Goal
|
||||||
|
List.of(new GuardTrigger()));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.factory.ChallengeFactoryHandler;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.KillGadgetTrigger;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class KillGadgetChallengeFactoryHandler implements ChallengeFactoryHandler {
|
||||||
|
@Override
|
||||||
|
public boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
// kill gadgets(explosive barrel) in time
|
||||||
|
// ActiveChallenge with 56,201,20,2,201,4
|
||||||
|
// open chest in time
|
||||||
|
// ActiveChallenge with 666,202,30,7,202,1
|
||||||
|
return challengeId == 201 || challengeId == 202;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
return new WorldChallenge(
|
||||||
|
scene, group,
|
||||||
|
challengeId, // Id
|
||||||
|
challengeIndex, // Index
|
||||||
|
List.of(param3, param6, 0),
|
||||||
|
param3, // Limit
|
||||||
|
param6, // Goal
|
||||||
|
List.of(new InTimeTrigger(), new KillGadgetTrigger())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.factory;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class KillMonsterChallengeFactoryHandler implements ChallengeFactoryHandler{
|
||||||
|
@Override
|
||||||
|
public boolean isThisType(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
// ActiveChallenge with 180,180,45,133108061,1,0
|
||||||
|
return challengeId == 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group) {
|
||||||
|
var realGroup = scene.getScriptManager().getGroupById(param4);
|
||||||
|
return new WorldChallenge(
|
||||||
|
scene, realGroup,
|
||||||
|
challengeId, // Id
|
||||||
|
challengeIndex, // Index
|
||||||
|
List.of(param5, param3),
|
||||||
|
param3, // Limit
|
||||||
|
param5, // Goal
|
||||||
|
List.of(new KillMonsterTrigger(), new InTimeTrigger())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
|
|
||||||
|
public abstract class ChallengeTrigger {
|
||||||
|
public void onBegin(WorldChallenge challenge){}
|
||||||
|
public void onFinish(WorldChallenge challenge){}
|
||||||
|
public void onMonsterDeath(WorldChallenge challenge, EntityMonster monster){}
|
||||||
|
public void onGadgetDeath(WorldChallenge challenge, EntityGadget gadget){}
|
||||||
|
public void onCheckTimeout(WorldChallenge challenge){}
|
||||||
|
public void onGadgetDamage(WorldChallenge challenge, EntityGadget gadget){}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
|
||||||
|
|
||||||
|
public class GuardTrigger extends KillMonsterTrigger{
|
||||||
|
@Override
|
||||||
|
public void onBegin(WorldChallenge challenge) {
|
||||||
|
super.onBegin(challenge);
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 2, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGadgetDamage(WorldChallenge challenge, EntityGadget gadget) {
|
||||||
|
var curHp = gadget.getFightProperties().get(FightProperty.FIGHT_PROP_CUR_HP.getId());
|
||||||
|
var maxHp = gadget.getFightProperties().get(FightProperty.FIGHT_PROP_BASE_HP.getId());
|
||||||
|
int percent = (int) (curHp / maxHp);
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 2, percent));
|
||||||
|
|
||||||
|
if(percent <= 0){
|
||||||
|
challenge.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
|
||||||
|
public class InTimeTrigger extends ChallengeTrigger{
|
||||||
|
@Override
|
||||||
|
public void onCheckTimeout(WorldChallenge challenge) {
|
||||||
|
var current = System.currentTimeMillis();
|
||||||
|
if(current - challenge.getStartedAt() > challenge.getTimeLimit() * 1000L){
|
||||||
|
challenge.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
|
||||||
|
|
||||||
|
public class KillGadgetTrigger extends ChallengeTrigger{
|
||||||
|
@Override
|
||||||
|
public void onBegin(WorldChallenge challenge) {
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 2, challenge.getScore().get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGadgetDeath(WorldChallenge challenge, EntityGadget gadget) {
|
||||||
|
var newScore = challenge.increaseScore();
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 2, newScore));
|
||||||
|
|
||||||
|
if(newScore >= challenge.getGoal()){
|
||||||
|
challenge.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package emu.grasscutter.game.dungeons.challenge.trigger;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
|
||||||
|
|
||||||
|
public class KillMonsterTrigger extends ChallengeTrigger{
|
||||||
|
@Override
|
||||||
|
public void onBegin(WorldChallenge challenge) {
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 1, challenge.getScore().get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMonsterDeath(WorldChallenge challenge, EntityMonster monster) {
|
||||||
|
var newScore = challenge.increaseScore();
|
||||||
|
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 1, newScore));
|
||||||
|
|
||||||
|
if(newScore >= challenge.getGoal()){
|
||||||
|
challenge.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,13 @@
|
|||||||
package emu.grasscutter.game.entity;
|
package emu.grasscutter.game.entity;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.excels.GadgetData;
|
import emu.grasscutter.data.excels.GadgetData;
|
||||||
|
import emu.grasscutter.game.entity.gadget.*;
|
||||||
import emu.grasscutter.game.props.EntityIdType;
|
import emu.grasscutter.game.props.EntityIdType;
|
||||||
import emu.grasscutter.game.props.EntityType;
|
import emu.grasscutter.game.props.EntityType;
|
||||||
|
import emu.grasscutter.game.props.LifeState;
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
import emu.grasscutter.game.world.World;
|
|
||||||
import emu.grasscutter.net.proto.ClientGadgetInfoOuterClass;
|
|
||||||
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
||||||
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
||||||
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
||||||
@ -23,15 +20,17 @@ import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
|
|||||||
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
||||||
import emu.grasscutter.net.proto.WorktopInfoOuterClass.WorktopInfo;
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGadget;
|
||||||
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
import emu.grasscutter.utils.ProtoHelper;
|
import emu.grasscutter.utils.ProtoHelper;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import lombok.ToString;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
|
||||||
|
|
||||||
|
@ToString(callSuper = true)
|
||||||
public class EntityGadget extends EntityBaseGadget {
|
public class EntityGadget extends EntityBaseGadget {
|
||||||
private final GadgetData data;
|
private final GadgetData data;
|
||||||
private final Position pos;
|
private final Position pos;
|
||||||
@ -39,7 +38,9 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
private int gadgetId;
|
private int gadgetId;
|
||||||
|
|
||||||
private int state;
|
private int state;
|
||||||
private IntSet worktopOptions;
|
private int pointType;
|
||||||
|
private GadgetContent content;
|
||||||
|
private SceneGadget metaGadget;
|
||||||
|
|
||||||
public EntityGadget(Scene scene, int gadgetId, Position pos) {
|
public EntityGadget(Scene scene, int gadgetId, Position pos) {
|
||||||
super(scene);
|
super(scene);
|
||||||
@ -50,19 +51,22 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
this.rot = new Position();
|
this.rot = new Position();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityGadget(Scene scene, int gadgetId, Position pos, GadgetContent content) {
|
||||||
|
this(scene, gadgetId, pos);
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
public GadgetData getGadgetData() {
|
public GadgetData getGadgetData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Position getPosition() {
|
public Position getPosition() {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return this.pos;
|
return this.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Position getRotation() {
|
public Position getRotation() {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return this.rot;
|
return this.rot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,33 +86,72 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntSet getWorktopOptions() {
|
public void updateState(int state){
|
||||||
return worktopOptions;
|
this.setState(state);
|
||||||
|
this.getScene().broadcastPacket(new PacketGadgetStateNotify(this, state));
|
||||||
|
getScene().getScriptManager().callEvent(EventType.EVENT_GADGET_STATE_CHANGE, new ScriptArgs(state, this.getConfigId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addWorktopOptions(int[] options) {
|
public int getPointType() {
|
||||||
if (this.worktopOptions == null) {
|
return pointType;
|
||||||
this.worktopOptions = new IntOpenHashSet();
|
|
||||||
}
|
|
||||||
Arrays.stream(options).forEach(this.worktopOptions::add);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeWorktopOption(int option) {
|
public void setPointType(int pointType) {
|
||||||
if (this.worktopOptions == null) {
|
this.pointType = pointType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GadgetContent getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated // Dont use!
|
||||||
|
public void setContent(GadgetContent content) {
|
||||||
|
this.content = this.content == null ? content : this.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SceneGadget getMetaGadget() {
|
||||||
|
return metaGadget;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetaGadget(SceneGadget metaGadget) {
|
||||||
|
this.metaGadget = metaGadget;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO refactor
|
||||||
|
public void buildContent() {
|
||||||
|
if (getContent() != null || getGadgetData() == null || getGadgetData().getType() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.worktopOptions.remove(option);
|
|
||||||
|
EntityType type = getGadgetData().getType();
|
||||||
|
GadgetContent content = switch (type) {
|
||||||
|
case GatherPoint -> new GadgetGatherPoint(this);
|
||||||
|
case Worktop -> new GadgetWorktop(this);
|
||||||
|
case RewardStatue -> new GadgetRewardStatue(this);
|
||||||
|
case Chest -> new GadgetChest(this);
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
public Int2FloatOpenHashMap getFightProperties() {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeath(int killerId) {
|
public void onCreate() {
|
||||||
|
// Lua event
|
||||||
|
getScene().getScriptManager().callEvent(EventType.EVENT_GADGET_CREATE, new ScriptArgs(this.getConfigId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeath(int killerId) {
|
||||||
|
if(getScene().getChallenge() != null){
|
||||||
|
getScene().getChallenge().onGadgetDeath(this);
|
||||||
|
}
|
||||||
|
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_GADGET_DIE, new ScriptArgs(this.getConfigId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -143,15 +186,16 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
.setIsEnableInteract(true)
|
.setIsEnableInteract(true)
|
||||||
.setAuthorityPeerId(this.getScene().getWorld().getHostPeerId());
|
.setAuthorityPeerId(this.getScene().getWorld().getHostPeerId());
|
||||||
|
|
||||||
if (this.getGadgetData().getType() == EntityType.Worktop && this.getWorktopOptions() != null) {
|
if (this.getContent() != null) {
|
||||||
WorktopInfo worktop = WorktopInfo.newBuilder()
|
this.getContent().onBuildProto(gadgetInfo);
|
||||||
.addAllOptionList(this.getWorktopOptions())
|
|
||||||
.build();
|
|
||||||
gadgetInfo.setWorktop(worktop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entityInfo.setGadget(gadgetInfo);
|
entityInfo.setGadget(gadgetInfo);
|
||||||
|
|
||||||
return entityInfo.build();
|
return entityInfo.build();
|
||||||
}
|
}
|
||||||
|
public void die() {
|
||||||
|
getScene().broadcastPacket(new PacketLifeStateChangeNotify(this, LifeState.LIFE_DEAD));
|
||||||
|
this.onDeath(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,11 @@ import emu.grasscutter.data.GameData;
|
|||||||
import emu.grasscutter.data.common.PropGrowCurve;
|
import emu.grasscutter.data.common.PropGrowCurve;
|
||||||
import emu.grasscutter.data.excels.MonsterCurveData;
|
import emu.grasscutter.data.excels.MonsterCurveData;
|
||||||
import emu.grasscutter.data.excels.MonsterData;
|
import emu.grasscutter.data.excels.MonsterData;
|
||||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.EntityIdType;
|
import emu.grasscutter.game.props.EntityIdType;
|
||||||
import emu.grasscutter.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
import emu.grasscutter.game.world.World;
|
|
||||||
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
||||||
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
||||||
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
||||||
@ -25,6 +23,7 @@ import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
|||||||
import emu.grasscutter.net.proto.SceneMonsterInfoOuterClass.SceneMonsterInfo;
|
import emu.grasscutter.net.proto.SceneMonsterInfoOuterClass.SceneMonsterInfo;
|
||||||
import emu.grasscutter.net.proto.SceneWeaponInfoOuterClass.SceneWeaponInfo;
|
import emu.grasscutter.net.proto.SceneWeaponInfoOuterClass.SceneWeaponInfo;
|
||||||
import emu.grasscutter.scripts.constants.EventType;
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
import emu.grasscutter.utils.ProtoHelper;
|
import emu.grasscutter.utils.ProtoHelper;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
||||||
@ -112,6 +111,12 @@ public class EntityMonster extends GameEntity {
|
|||||||
this.poseId = poseId;
|
this.poseId = poseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
// Lua event
|
||||||
|
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_LIVE, new ScriptArgs(this.getConfigId()));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void damage(float amount, int killerId) {
|
public void damage(float amount, int killerId) {
|
||||||
// Get HP before damage.
|
// Get HP before damage.
|
||||||
@ -135,8 +140,8 @@ public class EntityMonster extends GameEntity {
|
|||||||
this.getScene().getDeadSpawnedEntities().add(getSpawnEntry());
|
this.getScene().getDeadSpawnedEntities().add(getSpawnEntry());
|
||||||
}
|
}
|
||||||
// first set the challenge data
|
// first set the challenge data
|
||||||
if (getScene().getChallenge() != null && getScene().getChallenge().getGroup().id == this.getGroupId()) {
|
if (getScene().getChallenge() != null) {
|
||||||
getScene().getChallenge().onMonsterDie(this);
|
getScene().getChallenge().onMonsterDeath(this);
|
||||||
}
|
}
|
||||||
if (getScene().getScriptManager().isInit() && this.getGroupId() > 0) {
|
if (getScene().getScriptManager().isInit() && this.getGroupId() > 0) {
|
||||||
if(getScene().getScriptManager().getScriptMonsterSpawnService() != null){
|
if(getScene().getScriptManager().getScriptMonsterSpawnService() != null){
|
||||||
@ -144,7 +149,9 @@ public class EntityMonster extends GameEntity {
|
|||||||
}
|
}
|
||||||
// prevent spawn monster after success
|
// prevent spawn monster after success
|
||||||
if(getScene().getChallenge() != null && getScene().getChallenge().inProgress()){
|
if(getScene().getChallenge() != null && getScene().getChallenge().inProgress()){
|
||||||
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, null);
|
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, new ScriptArgs().setParam1(this.getConfigId()));
|
||||||
|
}else if(getScene().getChallenge() == null){
|
||||||
|
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, new ScriptArgs().setParam1(this.getConfigId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
81
src/main/java/emu/grasscutter/game/entity/EntityNPC.java
Normal file
81
src/main/java/emu/grasscutter/game/entity/EntityNPC.java
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package emu.grasscutter.game.entity;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.props.EntityIdType;
|
||||||
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.net.proto.*;
|
||||||
|
import emu.grasscutter.scripts.data.SceneNPC;
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||||
|
|
||||||
|
public class EntityNPC extends GameEntity{
|
||||||
|
|
||||||
|
private final Position position;
|
||||||
|
private final Position rotation;
|
||||||
|
private final SceneNPC metaNpc;
|
||||||
|
private final int suiteId;
|
||||||
|
|
||||||
|
public EntityNPC(Scene scene, SceneNPC metaNPC, int blockId, int suiteId) {
|
||||||
|
super(scene);
|
||||||
|
this.id = getScene().getWorld().getNextEntityId(EntityIdType.NPC);
|
||||||
|
setConfigId(metaNPC.config_id);
|
||||||
|
setGroupId(metaNPC.group.id);
|
||||||
|
setBlockId(blockId);
|
||||||
|
this.suiteId = suiteId;
|
||||||
|
this.position = metaNPC.pos.clone();
|
||||||
|
this.rotation = metaNPC.rot.clone();
|
||||||
|
this.metaNpc = metaNPC;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Int2FloatOpenHashMap getFightProperties() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Position getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Position getRotation() {
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSuiteId() {
|
||||||
|
return suiteId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
|
||||||
|
|
||||||
|
EntityAuthorityInfoOuterClass.EntityAuthorityInfo authority = EntityAuthorityInfoOuterClass.EntityAuthorityInfo.newBuilder()
|
||||||
|
.setAbilityInfo(AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo.newBuilder())
|
||||||
|
.setRendererChangedInfo(EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo.newBuilder())
|
||||||
|
.setAiInfo(SceneEntityAiInfoOuterClass.SceneEntityAiInfo.newBuilder()
|
||||||
|
.setIsAiOpen(true)
|
||||||
|
.setBornPos(getPosition().toProto()))
|
||||||
|
.setBornPos(getPosition().toProto())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SceneEntityInfoOuterClass.SceneEntityInfo.Builder entityInfo = SceneEntityInfoOuterClass.SceneEntityInfo.newBuilder()
|
||||||
|
.setEntityId(getId())
|
||||||
|
.setEntityType(ProtEntityTypeOuterClass.ProtEntityType.PROT_ENTITY_TYPE_NPC)
|
||||||
|
.setMotionInfo(MotionInfoOuterClass.MotionInfo.newBuilder()
|
||||||
|
.setPos(getPosition().toProto())
|
||||||
|
.setRot(getRotation().toProto())
|
||||||
|
.setSpeed(VectorOuterClass.Vector.newBuilder()))
|
||||||
|
.addAnimatorParaList(AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair.newBuilder())
|
||||||
|
.setEntityClientData(EntityClientDataOuterClass.EntityClientData.newBuilder())
|
||||||
|
.setEntityAuthorityInfo(authority)
|
||||||
|
.setLifeState(1);
|
||||||
|
|
||||||
|
|
||||||
|
entityInfo.setNpc(SceneNpcInfoOuterClass.SceneNpcInfo.newBuilder()
|
||||||
|
.setNpcId(metaNpc.npc_id)
|
||||||
|
.setBlockId(getBlockId())
|
||||||
|
.build());
|
||||||
|
|
||||||
|
return entityInfo.build();
|
||||||
|
}
|
||||||
|
}
|
@ -108,10 +108,6 @@ public abstract class GameEntity {
|
|||||||
this.lastMoveReliableSeq = lastMoveReliableSeq;
|
this.lastMoveReliableSeq = lastMoveReliableSeq;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract SceneEntityInfo toProto();
|
|
||||||
|
|
||||||
public abstract void onDeath(int killerId);
|
|
||||||
|
|
||||||
public void setFightProperty(FightProperty prop, float value) {
|
public void setFightProperty(FightProperty prop, float value) {
|
||||||
this.getFightProperties().put(prop.getId(), value);
|
this.getFightProperties().put(prop.getId(), value);
|
||||||
}
|
}
|
||||||
@ -219,4 +215,21 @@ public abstract class GameEntity {
|
|||||||
getScene().killEntity(this, killerId);
|
getScene().killEntity(this, killerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when this entity is added to the world
|
||||||
|
*/
|
||||||
|
public void onCreate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when this entity dies
|
||||||
|
* @param killerId Entity id of the entity that killed this entity
|
||||||
|
*/
|
||||||
|
public void onDeath(int killerId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract SceneEntityInfo toProto();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.net.proto.BossChestInfoOuterClass.BossChestInfo;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass.InterOpType;
|
||||||
|
import emu.grasscutter.net.proto.InteractTypeOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
||||||
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
|
import emu.grasscutter.scripts.constants.ScriptGadgetState;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
||||||
|
|
||||||
|
public class GadgetChest extends GadgetContent {
|
||||||
|
|
||||||
|
public GadgetChest(EntityGadget gadget) {
|
||||||
|
super(gadget);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onInteract(Player player, InterOpType opType) {
|
||||||
|
var chestInteractHandlerMap = getGadget().getScene().getWorld().getServer().getWorldDataManager().getChestInteractHandlerMap();
|
||||||
|
var handler = chestInteractHandlerMap.get(getGadget().getGadgetData().getJsonName());
|
||||||
|
if(handler == null){
|
||||||
|
Grasscutter.getLogger().warn("Could not found the handler of this type of Chests {}", getGadget().getGadgetData().getJsonName());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(opType == InterOpType.INTER_OP_TYPE_START && handler.isTwoStep()){
|
||||||
|
player.sendPacket(new PacketGadgetInteractRsp(getGadget(), InteractType.INTERACT_TYPE_OPEN_CHEST, InterOpType.INTER_OP_TYPE_START));
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
var success = handler.onInteract(this, player);
|
||||||
|
if (!success){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getGadget().updateState(ScriptGadgetState.ChestOpened);
|
||||||
|
player.sendPacket(new PacketGadgetInteractRsp(this.getGadget(), InteractTypeOuterClass.InteractType.INTERACT_TYPE_OPEN_CHEST));
|
||||||
|
// let the chest disappear
|
||||||
|
getGadget().die();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBuildProto(SceneGadgetInfo.Builder gadgetInfo) {
|
||||||
|
if(getGadget().getMetaGadget() == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bossChest = getGadget().getMetaGadget().boss_chest;
|
||||||
|
if(bossChest != null){
|
||||||
|
var players = getGadget().getScene().getPlayers().stream().map(Player::getUid).toList();
|
||||||
|
|
||||||
|
gadgetInfo.setBossChest(BossChestInfo.newBuilder()
|
||||||
|
.setMonsterConfigId(bossChest.monster_config_id)
|
||||||
|
.setResin(bossChest.resin)
|
||||||
|
.addAllQualifyUidList(players)
|
||||||
|
.addAllRemainUidList(players)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
|
|
||||||
|
public abstract class GadgetContent {
|
||||||
|
private final EntityGadget gadget;
|
||||||
|
|
||||||
|
public GadgetContent(EntityGadget gadget) {
|
||||||
|
this.gadget = gadget;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityGadget getGadget() {
|
||||||
|
return gadget;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType);
|
||||||
|
|
||||||
|
public abstract void onBuildProto(SceneGadgetInfo.Builder gadgetInfo);
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.excels.GatherData;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
|
import emu.grasscutter.net.proto.GatherGadgetInfoOuterClass.GatherGadgetInfo;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
|
|
||||||
|
public class GadgetGatherPoint extends GadgetContent {
|
||||||
|
private GatherData gatherData;
|
||||||
|
|
||||||
|
public GadgetGatherPoint(EntityGadget gadget) {
|
||||||
|
super(gadget);
|
||||||
|
this.gatherData = GameData.getGatherDataMap().get(gadget.getPointType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public GatherData getGatherData() {
|
||||||
|
return gatherData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getItemId() {
|
||||||
|
return getGatherData().getItemId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
|
GameItem item = new GameItem(gatherData.getItemId(), 1);
|
||||||
|
|
||||||
|
player.getInventory().addItem(item, ActionReason.Gather);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBuildProto(SceneGadgetInfo.Builder gadgetInfo) {
|
||||||
|
GatherGadgetInfo gatherGadgetInfo = GatherGadgetInfo.newBuilder()
|
||||||
|
.setItemId(this.getItemId())
|
||||||
|
.setIsForbidGuest(this.getGatherData().isForbidGuest())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
gadgetInfo.setGatherGadget(gatherGadgetInfo);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.dungeons.challenge.DungeonChallenge;
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
||||||
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
||||||
|
|
||||||
|
public class GadgetRewardStatue extends GadgetContent {
|
||||||
|
|
||||||
|
public GadgetRewardStatue(EntityGadget gadget) {
|
||||||
|
super(gadget);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
|
if (player.getScene().getChallenge() != null && player.getScene().getChallenge() instanceof DungeonChallenge dungeonChallenge) {
|
||||||
|
dungeonChallenge.getStatueDrops(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.sendPacket(new PacketGadgetInteractRsp(getGadget(), InteractType.INTERACT_TYPE_OPEN_STATUE));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBuildProto(SceneGadgetInfo.Builder gadgetInfo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.net.proto.InterOpTypeOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
|
import emu.grasscutter.net.proto.WorktopInfoOuterClass.WorktopInfo;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
|
||||||
|
public class GadgetWorktop extends GadgetContent {
|
||||||
|
private IntSet worktopOptions;
|
||||||
|
|
||||||
|
public GadgetWorktop(EntityGadget gadget) {
|
||||||
|
super(gadget);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntSet getWorktopOptions() {
|
||||||
|
return worktopOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWorktopOptions(int[] options) {
|
||||||
|
if (this.worktopOptions == null) {
|
||||||
|
this.worktopOptions = new IntOpenHashSet();
|
||||||
|
}
|
||||||
|
Arrays.stream(options).forEach(this.worktopOptions::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeWorktopOption(int option) {
|
||||||
|
if (this.worktopOptions == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.worktopOptions.remove(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onInteract(Player player, InterOpTypeOuterClass.InterOpType opType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBuildProto(SceneGadgetInfo.Builder gadgetInfo) {
|
||||||
|
if (this.worktopOptions == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorktopInfo worktop = WorktopInfo.newBuilder()
|
||||||
|
.addAllOptionList(this.getWorktopOptions())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
gadgetInfo.setWorktop(worktop);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget.chest;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
|
import emu.grasscutter.game.entity.gadget.GadgetChest;
|
||||||
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketGadgetAutoPickDropInfoNotify;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BossChestInteractHandler implements ChestInteractHandler{
|
||||||
|
@Override
|
||||||
|
public boolean isTwoStep() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInteract(GadgetChest chest, Player player) {
|
||||||
|
var worldDataManager = chest.getGadget().getScene().getWorld().getServer().getWorldDataManager();
|
||||||
|
var monster = chest.getGadget().getMetaGadget().group.monsters.get(chest.getGadget().getMetaGadget().boss_chest.monster_config_id);
|
||||||
|
var reward = worldDataManager.getRewardByBossId(monster.monster_id);
|
||||||
|
|
||||||
|
if(reward == null){
|
||||||
|
Grasscutter.getLogger().warn("Could not found the reward of boss monster {}", monster.monster_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<GameItem> rewards = new ArrayList<>();
|
||||||
|
for (ItemParamData param : reward.getPreviewItems()) {
|
||||||
|
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
player.getInventory().addItems(rewards, ActionReason.OpenWorldBossChest);
|
||||||
|
player.sendPacket(new PacketGadgetAutoPickDropInfoNotify(rewards));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget.chest;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.entity.gadget.GadgetChest;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
|
||||||
|
public interface ChestInteractHandler {
|
||||||
|
|
||||||
|
boolean isTwoStep();
|
||||||
|
|
||||||
|
boolean onInteract(GadgetChest chest, Player player);
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package emu.grasscutter.game.entity.gadget.chest;
|
||||||
|
|
||||||
|
import emu.grasscutter.game.entity.gadget.GadgetChest;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.world.ChestReward;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class NormalChestInteractHandler implements ChestInteractHandler {
|
||||||
|
private final ChestReward chestReward;
|
||||||
|
|
||||||
|
public NormalChestInteractHandler(ChestReward rewardData){
|
||||||
|
this.chestReward = rewardData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTwoStep() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInteract(GadgetChest chest, Player player) {
|
||||||
|
player.earnExp(chestReward.getAdvExp());
|
||||||
|
player.getInventory().addItem(201, chestReward.getResin());
|
||||||
|
|
||||||
|
var mora = chestReward.getMora() * (1 + (player.getWorldLevel() - 1) * 0.5);
|
||||||
|
player.getInventory().addItem(202, (int)mora);
|
||||||
|
|
||||||
|
for(int i=0;i<chestReward.getContent().size();i++){
|
||||||
|
chest.getGadget().getScene().addItemEntity(chestReward.getContent().get(i).getItemId(), chestReward.getContent().get(i).getCount(), chest.getGadget());
|
||||||
|
}
|
||||||
|
|
||||||
|
var random = new Random(System.currentTimeMillis());
|
||||||
|
for(int i=0;i<chestReward.getRandomCount();i++){
|
||||||
|
var index = random.nextInt(chestReward.getRandomContent().size());
|
||||||
|
var item = chestReward.getRandomContent().get(index);
|
||||||
|
chest.getGadget().getScene().addItemEntity(item.getItemId(), item.getCount(), chest.getGadget());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package emu.grasscutter.game.home;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import dev.morphia.annotations.Id;
|
||||||
|
import emu.grasscutter.net.proto.FurnitureMakeDataOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.FurnitureMakeSlotOuterClass;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
@Builder(builderMethodName = "of")
|
||||||
|
public class FurnitureMakeSlotItem {
|
||||||
|
@Id
|
||||||
|
int index;
|
||||||
|
int makeId;
|
||||||
|
int avatarId;
|
||||||
|
int beginTime;
|
||||||
|
int durTime;
|
||||||
|
|
||||||
|
public FurnitureMakeDataOuterClass.FurnitureMakeData toProto() {
|
||||||
|
return FurnitureMakeDataOuterClass.FurnitureMakeData.newBuilder()
|
||||||
|
.setIndex(index)
|
||||||
|
.setAvatarId(avatarId)
|
||||||
|
.setMakeId(makeId)
|
||||||
|
.setBeginTime(beginTime)
|
||||||
|
.setDurTime(durTime)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
80
src/main/java/emu/grasscutter/game/home/GameHome.java
Normal file
80
src/main/java/emu/grasscutter/game/home/GameHome.java
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package emu.grasscutter.game.home;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import dev.morphia.annotations.Id;
|
||||||
|
import dev.morphia.annotations.IndexOptions;
|
||||||
|
import dev.morphia.annotations.Indexed;
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.excels.HomeWorldLevelData;
|
||||||
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.server.packet.send.*;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@Entity(value = "homes", useDiscriminator = false)
|
||||||
|
@Data
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
@Builder(builderMethodName = "of")
|
||||||
|
public class GameHome {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
String id;
|
||||||
|
|
||||||
|
@Indexed(options = @IndexOptions(unique = true))
|
||||||
|
long ownerUid;
|
||||||
|
|
||||||
|
int level;
|
||||||
|
int exp;
|
||||||
|
List<FurnitureMakeSlotItem> furnitureMakeSlotItemList;
|
||||||
|
ConcurrentHashMap<Integer, HomeSceneItem> sceneMap;
|
||||||
|
|
||||||
|
public void save(){
|
||||||
|
DatabaseHelper.saveHome(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameHome getByUid(Integer uid){
|
||||||
|
var home = DatabaseHelper.getHomeByUid(uid);
|
||||||
|
if (home == null) {
|
||||||
|
home = GameHome.create(uid);
|
||||||
|
}
|
||||||
|
return home;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameHome create(Integer uid){
|
||||||
|
return GameHome.of()
|
||||||
|
.ownerUid(uid)
|
||||||
|
.level(1)
|
||||||
|
.sceneMap(new ConcurrentHashMap<>())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HomeSceneItem getHomeSceneItem(int sceneId) {
|
||||||
|
return sceneMap.computeIfAbsent(sceneId, e -> {
|
||||||
|
var defaultItem = GameData.getHomeworldDefaultSaveData().get(sceneId);
|
||||||
|
if (defaultItem != null){
|
||||||
|
Grasscutter.getLogger().info("Set player {} home {} to initial setting", ownerUid, sceneId);
|
||||||
|
return HomeSceneItem.parseFrom(defaultItem, sceneId);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onOwnerLogin(Player player) {
|
||||||
|
player.getSession().send(new PacketHomeBasicInfoNotify(player, false));
|
||||||
|
player.getSession().send(new PacketPlayerHomeCompInfoNotify(player));
|
||||||
|
player.getSession().send(new PacketHomeComfortInfoNotify(player));
|
||||||
|
player.getSession().send(new PacketFurnitureCurModuleArrangeCountNotify());
|
||||||
|
player.getSession().send(new PacketHomeMarkPointNotify(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
public HomeWorldLevelData getLevelData(){
|
||||||
|
return GameData.getHomeWorldLevelDataMap().get(level);
|
||||||
|
}
|
||||||
|
}
|
37
src/main/java/emu/grasscutter/game/home/HomeAnimalItem.java
Normal file
37
src/main/java/emu/grasscutter/game/home/HomeAnimalItem.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package emu.grasscutter.game.home;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import emu.grasscutter.net.proto.HomeAnimalDataOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.HomeFurnitureDataOuterClass;
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
@Builder(builderMethodName = "of")
|
||||||
|
public class HomeAnimalItem {
|
||||||
|
int furnitureId;
|
||||||
|
Position spawnPos;
|
||||||
|
Position spawnRot;
|
||||||
|
|
||||||
|
public HomeAnimalDataOuterClass.HomeAnimalData toProto(){
|
||||||
|
return HomeAnimalDataOuterClass.HomeAnimalData.newBuilder()
|
||||||
|
.setFurnitureId(furnitureId)
|
||||||
|
.setSpawnPos(spawnPos.toProto())
|
||||||
|
.setSpawnRot(spawnRot.toProto())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HomeAnimalItem parseFrom(HomeAnimalDataOuterClass.HomeAnimalData homeAnimalData) {
|
||||||
|
return HomeAnimalItem.of()
|
||||||
|
.furnitureId(homeAnimalData.getFurnitureId())
|
||||||
|
.spawnPos(new Position(homeAnimalData.getSpawnPos()))
|
||||||
|
.spawnRot(new Position(homeAnimalData.getSpawnRot()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
83
src/main/java/emu/grasscutter/game/home/HomeBlockItem.java
Normal file
83
src/main/java/emu/grasscutter/game/home/HomeBlockItem.java
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package emu.grasscutter.game.home;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import dev.morphia.annotations.Id;
|
||||||
|
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
|
||||||
|
import emu.grasscutter.net.proto.HomeBlockArrangementInfoOuterClass.HomeBlockArrangementInfo;
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
@Builder(builderMethodName = "of")
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
public class HomeBlockItem {
|
||||||
|
@Id
|
||||||
|
int blockId;
|
||||||
|
boolean unlocked;
|
||||||
|
List<HomeFurnitureItem> deployFurnitureList;
|
||||||
|
List<HomeFurnitureItem> persistentFurnitureList;
|
||||||
|
List<HomeAnimalItem> deployAnimalList;
|
||||||
|
List<HomeNPCItem> deployNPCList;
|
||||||
|
|
||||||
|
public void update(HomeBlockArrangementInfo homeBlockArrangementInfo) {
|
||||||
|
this.blockId = homeBlockArrangementInfo.getBlockId();
|
||||||
|
|
||||||
|
this.deployFurnitureList = homeBlockArrangementInfo.getDeployFurniureListList().stream()
|
||||||
|
.map(HomeFurnitureItem::parseFrom)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
this.persistentFurnitureList = homeBlockArrangementInfo.getPersistentFurnitureListList().stream()
|
||||||
|
.map(HomeFurnitureItem::parseFrom)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
this.deployAnimalList = homeBlockArrangementInfo.getDeployAnimalListList().stream()
|
||||||
|
.map(HomeAnimalItem::parseFrom)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
this.deployNPCList = homeBlockArrangementInfo.getDeployNpcListList().stream()
|
||||||
|
.map(HomeNPCItem::parseFrom)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int calComfort(){
|
||||||
|
return this.deployFurnitureList.stream()
|
||||||
|
.mapToInt(HomeFurnitureItem::getComfort)
|
||||||
|
.sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HomeBlockArrangementInfo toProto() {
|
||||||
|
var proto = HomeBlockArrangementInfo.newBuilder()
|
||||||
|
.setBlockId(blockId)
|
||||||
|
.setIsUnlocked(unlocked)
|
||||||
|
.setComfortValue(calComfort());
|
||||||
|
|
||||||
|
this.deployFurnitureList.forEach(f -> proto.addDeployFurniureList(f.toProto()));
|
||||||
|
this.persistentFurnitureList.forEach(f -> proto.addPersistentFurnitureList(f.toProto()));
|
||||||
|
this.deployAnimalList.forEach(f -> proto.addDeployAnimalList(f.toProto()));
|
||||||
|
this.deployNPCList.forEach(f -> proto.addDeployNpcList(f.toProto()));
|
||||||
|
|
||||||
|
return proto.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HomeBlockItem parseFrom(HomeworldDefaultSaveData.HomeBlock homeBlock) {
|
||||||
|
// create from default setting
|
||||||
|
return HomeBlockItem.of()
|
||||||
|
.blockId(homeBlock.getBlockId())
|
||||||
|
.unlocked(homeBlock.getFurnitures() != null)
|
||||||
|
.deployFurnitureList(
|
||||||
|
homeBlock.getFurnitures() == null ? List.of() :
|
||||||
|
homeBlock.getFurnitures().stream()
|
||||||
|
.map(HomeFurnitureItem::parseFrom)
|
||||||
|
.toList())
|
||||||
|
.deployAnimalList(List.of())
|
||||||
|
.deployNPCList(List.of())
|
||||||
|
.persistentFurnitureList(List.of())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user