Compare commits

..

4 commits

Author SHA1 Message Date
YYHEggEgg
3b892f151e gacha up command implementation 2024-08-07 01:03:19 +08:00
YYHEggEgg
436e691245 QuickMenu bugfix 2024-08-06 23:30:16 +08:00
YYHEggEgg
bb058b451d Separate Gacha logic & DTO, Fix items issue 2024-08-06 22:58:24 +08:00
YYHEggEgg
b2401d566b Support teleport map, mod button, post girl, nickname init 2024-08-06 22:43:45 +08:00
53 changed files with 172 additions and 11211 deletions

View file

@ -1,266 +0,0 @@
[
{
"ID": 50001,
"BuddyType": 1,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_50001",
"DIIDBBGLDOL": "Bangboo_Name_50001",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 9831098947874880184
},
{
"ID": 53001,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53001",
"DIIDBBGLDOL": "Bangboo_Name_53001",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 8017298617212498953
},
{
"ID": 53002,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53002",
"DIIDBBGLDOL": "Bangboo_Name_53002",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 15759244567804428825
},
{
"ID": 53003,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53003",
"DIIDBBGLDOL": "Bangboo_Name_53003",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 793541769103470830
},
{
"ID": 53004,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53004",
"DIIDBBGLDOL": "Bangboo_Name_53004",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 15333283710424173893
},
{
"ID": 53005,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53005",
"DIIDBBGLDOL": "Bangboo_Name_53005",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 6625485447473768309
},
{
"ID": 53006,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53006",
"DIIDBBGLDOL": "Bangboo_Name_53006",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 12516213533679239810
},
{
"ID": 53007,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53007",
"DIIDBBGLDOL": "Bangboo_Name_53007",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 1205030983673817181
},
{
"ID": 53008,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53008",
"DIIDBBGLDOL": "Bangboo_Name_53008",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 825481331324073038
},
{
"ID": 53009,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53009",
"DIIDBBGLDOL": "Bangboo_Name_53009",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 1109142289374885163
},
{
"ID": 53010,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53010",
"DIIDBBGLDOL": "Bangboo_Name_53010",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 7654740197435466664
},
{
"ID": 53011,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53011",
"DIIDBBGLDOL": "Bangboo_Name_53011",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 13043263780191768021
},
{
"ID": 53012,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_53012",
"DIIDBBGLDOL": "Bangboo_Name_53012",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 2166541009547495725
},
{
"ID": 54001,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_54001",
"DIIDBBGLDOL": "Bangboo_Name_54001",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 12126171553945369848
},
{
"ID": 54002,
"BuddyType": 2,
"ECHNDHDIIAC": 3,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_54002",
"DIIDBBGLDOL": "Bangboo_Name_54002",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 13558320022686804846
},
{
"ID": 54003,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_54003",
"DIIDBBGLDOL": "Bangboo_Name_54003",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 9057893760084610210
},
{
"ID": 54004,
"BuddyType": 2,
"ECHNDHDIIAC": 2,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_54004",
"DIIDBBGLDOL": "Bangboo_Name_54004",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 7098007717545413607
},
{
"ID": 54005,
"BuddyType": 2,
"ECHNDHDIIAC": 1,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_54005",
"DIIDBBGLDOL": "Bangboo_Name_54005",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 7896901026978333696
},
{
"ID": 54006,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_54006",
"DIIDBBGLDOL": "Bangboo_Name_54006",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 15413390933002967244
},
{
"ID": 54008,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_54008",
"DIIDBBGLDOL": "Bangboo_Name_54008",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 13745481736816990381
},
{
"ID": 54009,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_54009",
"DIIDBBGLDOL": "Bangboo_Name_54009",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 4565374391606395253
},
{
"ID": 54013,
"BuddyType": 2,
"ECHNDHDIIAC": 0,
"OHLKAFPBJHD": 0,
"GDDJBFHBJNK": 1,
"LAFKHMCKNIO": "Bangboo_Name_en_54013",
"DIIDBBGLDOL": "Bangboo_Name_54013",
"PCNEIBEDMCO": "BK_Eous",
"HIMPMHKGGIC": "",
"ANDDIMCDBME": 4076165347655962714
}
]

View file

@ -1,519 +0,0 @@
[
{
"RobotBuddyID": 19053001,
"BuddyID": 53001,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053001,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053002,
"BuddyID": 53002,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053002,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053003,
"BuddyID": 53003,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053003,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053004,
"BuddyID": 53004,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053004,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053005,
"BuddyID": 53005,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053005,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053006,
"BuddyID": 53006,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053006,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053007,
"BuddyID": 53007,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053007,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053008,
"BuddyID": 53008,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053008,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053009,
"BuddyID": 53009,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053009,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053010,
"BuddyID": 53010,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053010,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053011,
"BuddyID": 53011,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053011,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19053012,
"BuddyID": 53012,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1053012,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19054001,
"BuddyID": 54001,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1054001,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19054002,
"BuddyID": 54002,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1054002,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19054003,
"BuddyID": 54003,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1054003,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19054004,
"BuddyID": 54004,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1054004,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19054005,
"BuddyID": 54005,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1054005,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19054006,
"BuddyID": 54006,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1054006,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19054008,
"BuddyID": 54008,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1054008,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19054009,
"BuddyID": 54009,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1054009,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 19054013,
"BuddyID": 54013,
"CharLevel": 20,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 1054013,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 101000404,
"BuddyID": 53006,
"CharLevel": 1,
"CharUpgradeLevel": 1,
"CharStar": 1,
"GHGKBFEKDND": 53006,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 101000504,
"BuddyID": 54005,
"CharLevel": 6,
"CharUpgradeLevel": 1,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1000010104,
"BuddyID": 54005,
"CharLevel": 9,
"CharUpgradeLevel": 1,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1000010204,
"BuddyID": 54005,
"CharLevel": 9,
"CharUpgradeLevel": 1,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1000010304,
"BuddyID": 54005,
"CharLevel": 9,
"CharUpgradeLevel": 1,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1000010604,
"BuddyID": 54005,
"CharLevel": 11,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1000010704,
"BuddyID": 54005,
"CharLevel": 12,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1000010804,
"BuddyID": 54005,
"CharLevel": 13,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001000404,
"BuddyID": 54005,
"CharLevel": 8,
"CharUpgradeLevel": 1,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001010104,
"BuddyID": 54005,
"CharLevel": 10,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001010204,
"BuddyID": 54005,
"CharLevel": 15,
"CharUpgradeLevel": 2,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001020204,
"BuddyID": 54002,
"CharLevel": 24,
"CharUpgradeLevel": 3,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001020304,
"BuddyID": 54002,
"CharLevel": 24,
"CharUpgradeLevel": 3,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001020404,
"BuddyID": 54002,
"CharLevel": 26,
"CharUpgradeLevel": 3,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001020904,
"BuddyID": 54002,
"CharLevel": 28,
"CharUpgradeLevel": 3,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001021104,
"BuddyID": 54009,
"CharLevel": 32,
"CharUpgradeLevel": 4,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001021204,
"BuddyID": 54009,
"CharLevel": 33,
"CharUpgradeLevel": 4,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001030204,
"BuddyID": 54005,
"CharLevel": 34,
"CharUpgradeLevel": 4,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001030304,
"BuddyID": 54004,
"CharLevel": 35,
"CharUpgradeLevel": 4,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001030404,
"BuddyID": 54004,
"CharLevel": 36,
"CharUpgradeLevel": 4,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1001030504,
"BuddyID": 54004,
"CharLevel": 38,
"CharUpgradeLevel": 4,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1009010104,
"BuddyID": 53006,
"CharLevel": 25,
"CharUpgradeLevel": 3,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1009010204,
"BuddyID": 53006,
"CharLevel": 35,
"CharUpgradeLevel": 4,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1009010304,
"BuddyID": 53006,
"CharLevel": 45,
"CharUpgradeLevel": 5,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1009010404,
"BuddyID": 53006,
"CharLevel": 55,
"CharUpgradeLevel": 6,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
},
{
"RobotBuddyID": 1009010504,
"BuddyID": 53006,
"CharLevel": 60,
"CharUpgradeLevel": 6,
"CharStar": 1,
"GHGKBFEKDND": 0,
"ACGEEJMKBBO": 0,
"INPPGCADDPO": 0,
"FMPOMKKHELJ": 0
}
]

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@ use serde::Deserialize;
use super::BattleEventConfigID; use super::BattleEventConfigID;
template_id!(ArchiveBattleQuest id); template_id!(ArchiveBattleQuest u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(ArchiveFileQuest id); template_id!(ArchiveFileQuest u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(AvatarBase id); template_id!(AvatarBase u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -2,7 +2,7 @@ use serde::Deserialize;
use super::OnceRewardID; use super::OnceRewardID;
template_id!(BattleEventConfig id); template_id!(BattleEventConfig u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -2,7 +2,7 @@ use serde::Deserialize;
use super::BattleEventConfigID; use super::BattleEventConfigID;
template_id!(BattleGroupConfig id); template_id!(BattleGroupConfig u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,11 +0,0 @@
use serde::Deserialize;
template_id!(BuddyBase id);
#[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct BuddyBaseTemplate {
#[serde(rename = "ID")]
pub id: BuddyBaseID,
pub buddy_type: u32,
}

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(HollowConfig id); template_id!(HollowConfig u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(HollowQuest id); template_id!(HollowQuest u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(Item id); template_id!(Item u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(MainCityBgmConfig id); template_id!(MainCityBgmConfig u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(MainCityDefaultObject tag_id); template_id!(MainCityDefaultObject u32 tag_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(MainCityObject tag_id); template_id!(MainCityObject u32 tag_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,31 +1,29 @@
use paste::paste; use paste::paste;
use std::sync::OnceLock; use std::sync::OnceLock;
use thiserror::Error;
use super::DataLoadError; use super::DataLoadError;
#[derive(Debug, Error)]
#[error("template with id {0} not found")]
pub struct TemplateNotFoundError(pub u32);
macro_rules! template_id { macro_rules! template_id {
($type_name:ident $id_field:ident) => { ($type_name:ident $underlying_type:ident $id_field:ident) => {
::paste::paste! { ::paste::paste! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, ::serde::Deserialize, ::serde::Serialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, ::serde::Deserialize, ::serde::Serialize)]
pub struct [<$type_name ID>](u32); pub struct [<$type_name ID>]($underlying_type);
impl [<$type_name ID>] { impl [<$type_name ID>] {
pub fn new(id: u32) -> Result<Self, super::TemplateNotFoundError> { pub fn new(id: $underlying_type) -> Option<Self> {
crate::tables::[<$type_name:snake _template_tb>]::iter() if crate::tables::[<$type_name:snake _template_tb>]::iter().any(|tmpl| tmpl.$id_field.value() == id) {
.any(|tmpl| tmpl.$id_field.value() == id) Some(Self(id))
.then_some(Self(id)).ok_or(super::TemplateNotFoundError(id)) }
else {
None
}
} }
pub const fn new_unchecked(id: u32) -> Self { pub fn new_unchecked(id: $underlying_type) -> Self {
Self(id) Self(id)
} }
pub fn value(&self) -> u32 { pub fn value(&self) -> $underlying_type {
self.0 self.0
} }
@ -78,7 +76,6 @@ macro_rules! template_tables {
template_tables! { template_tables! {
AvatarBaseTemplate; AvatarBaseTemplate;
BuddyBaseTemplate;
UnlockConfigTemplate; UnlockConfigTemplate;
SectionConfigTemplate; SectionConfigTemplate;
ProcedureConfigTemplate; ProcedureConfigTemplate;
@ -101,6 +98,4 @@ template_tables! {
QuickFuncTemplate; QuickFuncTemplate;
TeleportConfigTemplate; TeleportConfigTemplate;
ItemTemplate; ItemTemplate;
RobotConfigTemplate;
RobotBuddyConfigTemplate;
} }

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(OnceReward reward_id); template_id!(OnceReward u32 reward_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(PostGirlConfig id); template_id!(PostGirlConfig u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(ProcedureConfig procedure_id); template_id!(ProcedureConfig u32 procedure_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(QuickAccess quick_func_id); template_id!(QuickAccess u32 quick_func_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(QuickFunc btn_id); template_id!(QuickFunc u32 btn_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,17 +0,0 @@
use serde::Deserialize;
use super::BuddyBaseID;
template_id!(RobotBuddyConfig robot_id);
#[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct RobotBuddyConfigTemplate {
#[serde(rename = "RobotBuddyID")]
pub robot_id: RobotBuddyConfigID,
#[serde(rename = "BuddyID")]
pub buddy_id: BuddyBaseID,
pub char_level: u32,
pub char_upgrade_level: u32,
pub char_star: u32,
}

View file

@ -1,24 +0,0 @@
use serde::Deserialize;
use super::{AvatarBaseID, WeaponID};
template_id!(RobotConfig robot_id);
#[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct RobotConfigTemplate {
#[serde(rename = "RobotID")]
pub robot_id: RobotConfigID,
#[serde(rename = "CharacterID")]
pub character_id: AvatarBaseID,
pub char_level: u32,
pub char_upgrade_level: u32,
pub char_star: u32,
pub skill_levels: Vec<u32>,
pub talent_level: u32,
#[serde(rename = "WeaponID")]
pub weapon_id: WeaponID,
pub weapon_level: u32,
pub weapon_upgrade_level: u32,
pub weapon_refine_level: u32,
}

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(SectionConfig section_id); template_id!(SectionConfig u32 section_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -2,7 +2,7 @@ use std::u32;
use serde::Deserialize; use serde::Deserialize;
template_id!(SubAreaData area_id); template_id!(SubAreaData u32 area_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(TeleportConfig teleport_id); template_id!(TeleportConfig i32 teleport_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -2,7 +2,7 @@ use serde::Deserialize;
use super::BattleEventConfigID; use super::BattleEventConfigID;
template_id!(TrainingQuest id); template_id!(TrainingQuest u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(UnlockConfig id); template_id!(UnlockConfig i32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -2,7 +2,7 @@ use std::u32;
use serde::Deserialize; use serde::Deserialize;
template_id!(VariableData id); template_id!(VariableData u32 id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
template_id!(Weapon item_id); template_id!(Weapon u32 item_id);
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]

View file

@ -1,4 +1,4 @@
use data::tables::{self, AvatarBaseID}; use data::tables::AvatarBaseID;
use proto::{AddAvatarPerformType, AddAvatarScNotify, PlayerSyncScNotify}; use proto::{AddAvatarPerformType, AddAvatarScNotify, PlayerSyncScNotify};
use crate::ServerState; use crate::ServerState;
@ -17,7 +17,7 @@ pub async fn add(
let uid = args[0].parse::<u32>()?; let uid = args[0].parse::<u32>()?;
let avatar_id = args[1].parse::<u32>()?; let avatar_id = args[1].parse::<u32>()?;
let Ok(avatar_id) = AvatarBaseID::new(avatar_id) else { let Some(avatar_id) = AvatarBaseID::new(avatar_id) else {
return Ok(format!("avatar with id {avatar_id} doesn't exist")); return Ok(format!("avatar with id {avatar_id} doesn't exist"));
}; };
@ -55,62 +55,3 @@ pub async fn add(
"successfully added avatar {avatar_id} to player {uid}" "successfully added avatar {avatar_id} to player {uid}"
)) ))
} }
pub async fn add_all(
args: ArgSlice<'_>,
state: &ServerState,
) -> Result<String, Box<dyn std::error::Error>> {
const USAGE: &str = "Usage: avatar add_all [player_uid]";
if args.len() != 1 {
return Ok(USAGE.to_string());
}
let uid = args[0].parse::<u32>()?;
let Some(player_lock) = state.player_mgr.get_player(uid).await else {
return Ok(String::from("player not found"));
};
let (session_id, avatar_sync, avatar_id_list) = {
let mut player = player_lock.lock().await;
let avatar_id_list = tables::avatar_base_template_tb::iter()
.filter(|tmpl| tmpl.id.value() < 2000 && !player.role_model.has_avatar(tmpl.id))
.map(|tmpl| tmpl.id)
.collect::<Vec<_>>();
avatar_id_list
.iter()
.for_each(|id| player.role_model.add_avatar(*id));
(
player.current_session_id(),
player.role_model.avatar_sync(),
avatar_id_list,
)
};
if let Some(session) = session_id.map(|id| state.session_mgr.get(id)).flatten() {
for id in avatar_id_list {
session
.notify(AddAvatarScNotify {
avatar_id: id.value(),
perform_type: AddAvatarPerformType::ShowPopup.into(),
..Default::default()
})
.await?;
}
session
.notify(PlayerSyncScNotify {
avatar: Some(avatar_sync),
..Default::default()
})
.await?;
} else {
state.player_mgr.save_and_remove(uid).await;
}
Ok(format!("successfully added all avatars to player {uid}"))
}

View file

@ -17,7 +17,7 @@ pub async fn add_weapon(
let uid = args[0].parse::<u32>()?; let uid = args[0].parse::<u32>()?;
let weapon_id = args[1].parse::<u32>()?; let weapon_id = args[1].parse::<u32>()?;
let Ok(weapon_id) = WeaponID::new(weapon_id) else { let Some(weapon_id) = WeaponID::new(weapon_id) else {
return Ok(format!("weapon with id {weapon_id} doesn't exist")); return Ok(format!("weapon with id {weapon_id} doesn't exist"));
}; };

View file

@ -86,10 +86,9 @@ impl CommandManager {
player::avatar "[player_uid] [avatar_id]" "changes player avatar for main city"; player::avatar "[player_uid] [avatar_id]" "changes player avatar for main city";
player::nickname "[player_uid] [nickname]" "changes player nickname"; player::nickname "[player_uid] [nickname]" "changes player nickname";
player::procedure "[player_uid] [procedure_id]" "changes current beginner procedure id, parameter -1 can be used for skipping it"; player::procedure "[player_uid] [procedure_id]" "changes current beginner procedure id, parameter -1 can be used for skipping it";
player::kick "[player_uid] [reason]" "kick the specified player (reason is optional)";
avatar::add "[player_uid] [avatar_id]" "gives avatar with specified id to player"; avatar::add "[player_uid] [avatar_id]" "gives avatar with specified id to player";
avatar::add_all "[player_uid]" "gives all avatars to player";
item::add_weapon "[player_uid] [weapon_id]" "gives weapon with specified id to player"; item::add_weapon "[player_uid] [weapon_id]" "gives weapon with specified id to player";
player::kick "[player_uid] [reason]" "kick the specified player (reason is optional)";
gacha::up "[player_uid]" "start a gacha UP setting guide (available for Bangboo pool)"; gacha::up "[player_uid]" "start a gacha UP setting guide (available for Bangboo pool)";
} }
} }

View file

@ -17,7 +17,7 @@ pub async fn avatar(
let uid = args[0].parse::<u32>()?; let uid = args[0].parse::<u32>()?;
let avatar_id = args[1].parse::<u32>()?; let avatar_id = args[1].parse::<u32>()?;
let Ok(avatar_id) = AvatarBaseID::new(avatar_id) else { let Some(avatar_id) = AvatarBaseID::new(avatar_id) else {
return Ok(format!("avatar with id {avatar_id} doesn't exist")); return Ok(format!("avatar with id {avatar_id} doesn't exist"));
}; };
@ -103,7 +103,7 @@ pub async fn procedure(
let procedure_id = args[1].parse::<i32>()?; let procedure_id = args[1].parse::<i32>()?;
let procedure_id = match procedure_id { let procedure_id = match procedure_id {
1.. => ProcedureConfigID::new(procedure_id as u32).ok(), 1.. => ProcedureConfigID::new(procedure_id as u32),
_ => None, _ => None,
}; };

View file

@ -1,8 +1,8 @@
use crate::logic::{game::LogicError, EOperator, ESystem}; use crate::logic::{EOperator, ESystem};
use super::*; use super::*;
use data::tables::{self, PostGirlConfigID, QuickFuncID}; use data::tables::{self, QuickFuncID};
pub async fn on_get_tips_info( pub async fn on_get_tips_info(
_session: &NetSession, _session: &NetSession,
@ -45,7 +45,7 @@ pub async fn on_get_client_systems_info(
teleport_data: Some(TeleportData { teleport_data: Some(TeleportData {
unlock_id_list: tables::teleport_config_template_tb::iter() unlock_id_list: tables::teleport_config_template_tb::iter()
.filter(|template| template.client_visible > 0) .filter(|template| template.client_visible > 0)
.map(|template| template.teleport_id.value() as i32) .map(|template| template.teleport_id.value())
.collect(), .collect(),
..Default::default() ..Default::default()
}), }),
@ -196,20 +196,22 @@ pub async fn on_interact_with_scene_object(
} }
pub async fn on_mod_quick_menu( pub async fn on_mod_quick_menu(
session: &NetSession, _session: &NetSession,
player: &mut Player, _player: &mut Player,
req: ModQuickMenuCsReq, _req: ModQuickMenuCsReq,
) -> NetResult<ModQuickMenuScRsp> { ) -> NetResult<ModQuickMenuScRsp> {
req.quick_access_data_list.iter().for_each(|data| { let mut quick_access_data_list: Vec<QuickAccessData> = vec![];
player for data in _req.quick_access_data_list.iter() {
.lock_model quick_access_data_list.push(
.mod_quick_access(data.quick_access_index, QuickFuncID::new(data.btn_id).ok()) _player
}); .lock_model
.mod_quick_access(data.quick_access_index, QuickFuncID::new(data.btn_id)),
session );
}
_session
.notify(PlayerSyncScNotify { .notify(PlayerSyncScNotify {
client_systems_sync: Some(ClientSystemsSync { client_systems_sync: Some(ClientSystemsSync {
quick_access_data_list: player.lock_model.quick_access_to_client(), quick_access_data_list: _player.lock_model.quick_access_to_client(),
..Default::default() ..Default::default()
}), }),
..Default::default() ..Default::default()
@ -223,33 +225,39 @@ pub async fn on_mod_quick_menu(
} }
pub async fn on_change_post_girl( pub async fn on_change_post_girl(
session: &NetSession, _session: &NetSession,
player: &mut Player, _player: &mut Player,
req: ChangePostGirlCsReq, _req: ChangePostGirlCsReq,
) -> NetResult<ChangePostGirlScRsp> { ) -> NetResult<ChangePostGirlScRsp> {
let post_girl_id = *req if _req.new_selected_post_girl_id_list.len() != 1 {
.new_selected_post_girl_id_list return Ok(ChangePostGirlScRsp {
.get(0) retcode: Retcode::RetFail.into(),
.ok_or(Retcode::RetFail)?;
let post_girl_id = PostGirlConfigID::new(post_girl_id).map_err(LogicError::from)?;
player.basic_data_model.selected_post_girl_id = Some(post_girl_id);
session
.notify(PlayerSyncScNotify {
client_systems_sync: Some(ClientSystemsSync {
post_girl_data: Some(PostGirlSync {
selected_post_girl_id_list: vec![post_girl_id.value()],
..Default::default()
}),
..Default::default()
}),
..Default::default() ..Default::default()
}) });
.await?; };
match tables::PostGirlConfigID::new(*_req.new_selected_post_girl_id_list.get(0).unwrap()) {
Ok(ChangePostGirlScRsp { Some(post_girl_id) => {
retcode: Retcode::RetSucc.into(), _player.basic_data_model.selected_post_girl_id = Some(post_girl_id);
..Default::default() _session
}) .notify(PlayerSyncScNotify {
client_systems_sync: Some(ClientSystemsSync {
post_girl_data: Some(PostGirlSync {
selected_post_girl_id_list: vec![post_girl_id.value()],
..Default::default()
}),
..Default::default()
}),
..Default::default()
})
.await?;
Ok(ChangePostGirlScRsp {
retcode: Retcode::RetSucc.into(),
..Default::default()
})
}
None => Ok(ChangePostGirlScRsp {
retcode: Retcode::RetFail.into(),
..Default::default()
}),
}
} }

View file

@ -123,7 +123,7 @@ pub async fn on_gacha_free_agent(
)?; )?;
let item_id = ItemID::new(req.avatar_id); let item_id = ItemID::new(req.avatar_id);
if item_id.is_err() { if let None = item_id {
return Err(NetError::from(Retcode::RetFail)); return Err(NetError::from(Retcode::RetFail));
} }
let item_id = item_id.unwrap(); let item_id = item_id.unwrap();
@ -157,7 +157,7 @@ pub async fn on_choose_gacha_up(
)?; )?;
let item_id = ItemID::new(req.item_id); let item_id = ItemID::new(req.item_id);
if item_id.is_err() { if let None = item_id {
return Err(NetError::from(Retcode::RetFail)); return Err(NetError::from(Retcode::RetFail));
} }
let item_id = item_id.unwrap(); let item_id = item_id.unwrap();
@ -200,18 +200,18 @@ fn add_item(
) -> NetResult<u32> { ) -> NetResult<u32> {
match item_type { match item_type {
GachaAddedItemType::Character => match AvatarBaseID::new(item_id.value()) { GachaAddedItemType::Character => match AvatarBaseID::new(item_id.value()) {
Ok(avatar_id) => { Some(avatar_id) => {
role_model.add_avatar(avatar_id); role_model.add_avatar(avatar_id);
Ok(0) Ok(0)
} }
Err(_) => { None => {
tracing::info!("add item failed for avatar id {item_id}"); tracing::info!("add item failed for avatar id {item_id}");
Err(NetError::from(Retcode::RetFail)) Err(NetError::from(Retcode::RetFail))
} }
}, },
GachaAddedItemType::Weapon => match WeaponID::new(item_id.value()) { GachaAddedItemType::Weapon => match WeaponID::new(item_id.value()) {
Ok(weapon_id) => Ok(item_model.add_weapon(weapon_id).value()), Some(weapon_id) => Ok(item_model.add_weapon(weapon_id).value()),
Err(_) => { None => {
tracing::info!("add item failed for weapon id {item_id}"); tracing::info!("add item failed for weapon id {item_id}");
Err(NetError::from(Retcode::RetFail)) Err(NetError::from(Retcode::RetFail))
} }

View file

@ -1,7 +1,5 @@
use data::tables::AvatarBaseID; use data::tables::AvatarBaseID;
use crate::logic::game::LogicError;
use super::*; use super::*;
pub async fn on_get_item_data( pub async fn on_get_item_data(
@ -25,7 +23,7 @@ pub async fn on_weapon_dress(
req: WeaponDressCsReq, req: WeaponDressCsReq,
) -> NetResult<WeaponDressScRsp> { ) -> NetResult<WeaponDressScRsp> {
player.dress_weapon( player.dress_weapon(
AvatarBaseID::new(req.avatar_id).map_err(LogicError::from)?, AvatarBaseID::new(req.avatar_id).ok_or(Retcode::RetFail)?,
req.weapon_uid.into(), req.weapon_uid.into(),
)?; )?;
@ -47,7 +45,7 @@ pub async fn on_weapon_un_dress(
player: &mut Player, player: &mut Player,
req: WeaponUnDressCsReq, req: WeaponUnDressCsReq,
) -> NetResult<WeaponUnDressScRsp> { ) -> NetResult<WeaponUnDressScRsp> {
let avatar_id = AvatarBaseID::new(req.avatar_id).map_err(LogicError::from)?; let avatar_id = AvatarBaseID::new(req.avatar_id).ok_or(Retcode::RetFail)?;
let avatar = player let avatar = player
.role_model .role_model
.avatar_list .avatar_list

View file

@ -22,7 +22,7 @@ pub async fn on_create_role(
player: &mut Player, player: &mut Player,
req: CreateRoleCsReq, req: CreateRoleCsReq,
) -> NetResult<CreateRoleScRsp> { ) -> NetResult<CreateRoleScRsp> {
let avatar_id = AvatarBaseID::new(req.avatar_id).map_err(LogicError::from)?; let avatar_id = AvatarBaseID::new(req.avatar_id).ok_or(Retcode::RetFail)?;
let GameInstance::Fresh(fresh_game) = &mut player.game_instance else { let GameInstance::Fresh(fresh_game) = &mut player.game_instance else {
return Err(NetError::from(Retcode::RetFail)); return Err(NetError::from(Retcode::RetFail));

View file

@ -88,7 +88,7 @@ pub async fn on_begin_archive_battle_quest(
player: &mut Player, player: &mut Player,
req: BeginArchiveBattleQuestCsReq, req: BeginArchiveBattleQuestCsReq,
) -> NetResult<BeginArchiveBattleQuestScRsp> { ) -> NetResult<BeginArchiveBattleQuestScRsp> {
let quest_id = ArchiveBattleQuestID::new(req.quest_id).map_err(LogicError::from)?; let quest_id = ArchiveBattleQuestID::new(req.quest_id).ok_or(Retcode::RetFail)?;
player.game_instance = GameInstance::Hollow( player.game_instance = GameInstance::Hollow(
HollowGame::create_archive_battle( HollowGame::create_archive_battle(

View file

@ -47,7 +47,7 @@ pub async fn on_advance_beginner_procedure(
}; };
let procedure_id = let procedure_id =
ProcedureConfigID::new(req.procedure_id as u32).map_err(LogicError::from)?; ProcedureConfigID::new(req.procedure_id as u32).ok_or(Retcode::RetFail)?;
fresh_game fresh_game
.procedure_mgr .procedure_mgr
@ -168,7 +168,7 @@ pub async fn on_start_trial_fighting_mission(
player: &mut Player, player: &mut Player,
req: StartTrialFightingMissionCsReq, req: StartTrialFightingMissionCsReq,
) -> NetResult<StartTrialFightingMissionScRsp> { ) -> NetResult<StartTrialFightingMissionScRsp> {
let quest_id = TrainingQuestID::new(req.quest_id).map_err(LogicError::from)?; let quest_id = TrainingQuestID::new(req.quest_id).ok_or(Retcode::RetFail)?;
player.game_instance = GameInstance::Hollow( player.game_instance = GameInstance::Hollow(
HollowGame::create_training_game(quest_id, ELocalPlayType::TrainingRoomFight, &req.avatars) HollowGame::create_training_game(quest_id, ELocalPlayType::TrainingRoomFight, &req.avatars)
@ -273,7 +273,7 @@ pub async fn on_enter_section(
player: &mut Player, player: &mut Player,
req: EnterSectionCsReq, req: EnterSectionCsReq,
) -> NetResult<EnterSectionScRsp> { ) -> NetResult<EnterSectionScRsp> {
let section_id = SectionConfigID::new(req.section_id).map_err(LogicError::from)?; let section_id = SectionConfigID::new(req.section_id).ok_or(Retcode::RetFail)?;
player.main_city_model.switch_section(section_id); player.main_city_model.switch_section(section_id);
player.init_frontend_game()?; player.init_frontend_game()?;
@ -311,7 +311,7 @@ pub async fn on_start_hollow_quest(
) -> NetResult<StartHollowQuestScRsp> { ) -> NetResult<StartHollowQuestScRsp> {
use crate::logic::{TimePeriodType, WeatherType}; use crate::logic::{TimePeriodType, WeatherType};
let quest_id = HollowQuestID::new(req.quest_id).map_err(LogicError::from)?; let quest_id = HollowQuestID::new(req.quest_id).ok_or(Retcode::RetFail)?;
let quest_type = EHollowQuestType::from(quest_id.template().hollow_quest_type); let quest_type = EHollowQuestType::from(quest_id.template().hollow_quest_type);
match quest_type { match quest_type {

View file

@ -2,17 +2,17 @@ use std::collections::HashMap;
use crate::logic::BuddyTeamType; use crate::logic::BuddyTeamType;
use super::unit::{AvatarUnit, AvatarUnitID, BuddyUnit, BuddyUnitID}; use super::unit::{AvatarUnit, BuddyUnit};
pub struct TeamDataItem { pub struct TeamDataItem {
pub avatar_member_list: Vec<AvatarUnit>, pub avatar_member_list: Vec<AvatarUnit>,
pub equipped_buddy_list: Vec<BuddyUnit>, pub equipped_buddy_list: Vec<BuddyUnit>,
} }
pub struct BuddyParam(pub BuddyUnitID, pub BuddyTeamType); pub struct BuddyParam(pub u32, pub BuddyTeamType);
impl TeamDataItem { impl TeamDataItem {
pub fn new(avatars: &[AvatarUnitID], buddy_params: &[BuddyParam]) -> Self { pub fn new(avatars: &[u32], buddy_params: &[BuddyParam]) -> Self {
Self { Self {
avatar_member_list: avatars avatar_member_list: avatars
.iter() .iter()

View file

@ -1,36 +1,17 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::logic::BaseProperty; use crate::logic::BaseProperty;
use data::tables::{AvatarBaseID, RobotConfigID};
use proto::AvatarUnitInfo; use proto::AvatarUnitInfo;
pub struct AvatarUnit { pub struct AvatarUnit {
pub avatar_id: AvatarUnitID, pub avatar_id: u32,
pub mp_property_override: HashMap<BaseProperty, i32>, pub mp_property_override: HashMap<BaseProperty, i32>,
} }
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum AvatarUnitID {
Base(AvatarBaseID),
Robot(RobotConfigID),
}
impl AvatarUnitID {
pub fn base_id(&self) -> AvatarBaseID {
match *self {
Self::Base(id) => id,
Self::Robot(id) => id.template().character_id,
}
}
}
impl AvatarUnit { impl AvatarUnit {
pub fn to_client(&self) -> AvatarUnitInfo { pub fn to_client(&self) -> AvatarUnitInfo {
AvatarUnitInfo { AvatarUnitInfo {
avatar_id: match self.avatar_id { avatar_id: self.avatar_id,
AvatarUnitID::Base(id) => id.value(),
AvatarUnitID::Robot(id) => id.value(),
},
mp_property_override_map: self mp_property_override_map: self
.mp_property_override .mp_property_override
.iter() .iter()

View file

@ -1,38 +1,19 @@
use std::collections::HashMap; use std::collections::HashMap;
use data::tables::{BuddyBaseID, RobotBuddyConfigID};
use proto::BuddyUnitInfo; use proto::BuddyUnitInfo;
use crate::logic::{BaseProperty, BuddyTeamType}; use crate::logic::{BaseProperty, BuddyTeamType};
pub struct BuddyUnit { pub struct BuddyUnit {
pub buddy_id: BuddyUnitID, pub buddy_id: u32,
pub buddy_team: BuddyTeamType, pub buddy_team: BuddyTeamType,
pub override_property_map: HashMap<BaseProperty, i32>, pub override_property_map: HashMap<BaseProperty, i32>,
} }
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BuddyUnitID {
Base(BuddyBaseID),
Robot(RobotBuddyConfigID),
}
impl BuddyUnitID {
pub fn base_id(&self) -> BuddyBaseID {
match *self {
Self::Base(id) => id,
Self::Robot(id) => id.template().buddy_id,
}
}
}
impl BuddyUnit { impl BuddyUnit {
pub fn to_client(&self) -> BuddyUnitInfo { pub fn to_client(&self) -> BuddyUnitInfo {
BuddyUnitInfo { BuddyUnitInfo {
buddy_id: match self.buddy_id { buddy_id: self.buddy_id,
BuddyUnitID::Base(id) => id.value(),
BuddyUnitID::Robot(id) => id.value(),
},
r#type: self.buddy_team.to_protocol().into(), r#type: self.buddy_team.to_protocol().into(),
mp_property_override_map: self mp_property_override_map: self
.override_property_map .override_property_map

View file

@ -1,5 +1,5 @@
mod avatar; mod avatar;
mod buddy; mod buddy;
pub use avatar::{AvatarUnit, AvatarUnitID}; pub use avatar::AvatarUnit;
pub use buddy::{BuddyUnit, BuddyUnitID}; pub use buddy::BuddyUnit;

View file

@ -509,7 +509,7 @@ fn determine_gacha_result<'bin, 'conf>(
// TODO: apply_on_owned_count in a context with bag // TODO: apply_on_owned_count in a context with bag
// TODO: That's what RoleModel should do, not me. // TODO: That's what RoleModel should do, not me.
if extra_items_policy.apply_on_owned_count == 0 { if extra_items_policy.apply_on_owned_count == 0 {
extra_item_id = ItemID::new(extra_items_policy.id).ok(); extra_item_id = ItemID::new(extra_items_policy.id);
extra_item_count = extra_items_policy.count; extra_item_count = extra_items_policy.count;
} }
} }

View file

@ -19,8 +19,8 @@ impl GachaExtraResources {
Some(bin) => { Some(bin) => {
let item_id_opt = ItemID::new(bin.extra_item_id); let item_id_opt = ItemID::new(bin.extra_item_id);
match item_id_opt { match item_id_opt {
Err(_) => None, None => None,
Ok(extra_item_id) => Some(Self { Some(extra_item_id) => Some(Self {
extra_item_id, extra_item_id,
extra_item_count: bin.extra_item_count, extra_item_count: bin.extra_item_count,
}), }),

View file

@ -1,7 +1,6 @@
use common::util; use common::util;
use data::tables::{ use data::tables::{
self, ArchiveBattleQuestID, AvatarBaseID, BattleEventConfigID, BuddyBaseID, HollowQuestID, self, ArchiveBattleQuestID, BattleEventConfigID, HollowQuestID, TrainingQuestID,
RobotBuddyConfigID, RobotConfigID, TrainingQuestID,
}; };
use proto::{DungeonInfo, DungeonItemData, FightSceneInfo, SceneInfo, WeatherPoolInfo}; use proto::{DungeonInfo, DungeonItemData, FightSceneInfo, SceneInfo, WeatherPoolInfo};
use thiserror::Error; use thiserror::Error;
@ -9,7 +8,7 @@ use thiserror::Error;
use crate::logic::{ use crate::logic::{
battle::{ battle::{
drop::FightDropPool, drop::FightDropPool,
unit::{AvatarUnit, AvatarUnitID, BuddyUnit, BuddyUnitID}, unit::{AvatarUnit, BuddyUnit},
BuddyParam, DungeonQuestManager, TeamDataItem, BuddyParam, DungeonQuestManager, TeamDataItem,
}, },
BuddyTeamType, EHollowQuestType, ELocalPlayType, ESceneType, TimePeriodType, WeatherType, BuddyTeamType, EHollowQuestType, ELocalPlayType, ESceneType, TimePeriodType, WeatherType,
@ -23,10 +22,6 @@ pub enum HollowGameError {
QuestTypeNotSupported(u32, EHollowQuestType), QuestTypeNotSupported(u32, EHollowQuestType),
#[error("Battle group not found, quest id: {0}")] #[error("Battle group not found, quest id: {0}")]
BattleGroupNotFound(u32), BattleGroupNotFound(u32),
#[error("Invalid avatar id: {0}")]
InvalidAvatarID(u32),
#[error("Invalid robot id: {0}")]
InvalidRobotID(u32),
} }
pub struct HollowGame { pub struct HollowGame {
@ -49,15 +44,6 @@ impl HollowGame {
) -> Result<Self, HollowGameError> { ) -> Result<Self, HollowGameError> {
let template = training_quest_id.template(); let template = training_quest_id.template();
let avatars = match avatars
.iter()
.map(|id| AvatarBaseID::new(*id).map(|id| AvatarUnitID::Base(id)))
.collect::<Result<Vec<_>, _>>()
{
Ok(avatars) => avatars,
Err(err) => return Err(HollowGameError::InvalidAvatarID(err.0)),
};
Ok(Self { Ok(Self {
quest_id: template.id.value(), quest_id: template.id.value(),
battle_event_id: template.battle_event_id, battle_event_id: template.battle_event_id,
@ -65,7 +51,7 @@ impl HollowGame {
weather: WeatherType::SunShine, weather: WeatherType::SunShine,
start_timestamp: util::cur_timestamp() as i64, start_timestamp: util::cur_timestamp() as i64,
play_type, play_type,
team_data: TeamDataItem::new(&avatars, &[]), team_data: TeamDataItem::new(avatars, &[]),
fight_drop_pool: FightDropPool::new(template.battle_event_id), fight_drop_pool: FightDropPool::new(template.battle_event_id),
quest_manager: DungeonQuestManager::default(), quest_manager: DungeonQuestManager::default(),
}) })
@ -79,20 +65,6 @@ impl HollowGame {
) -> Result<Self, HollowGameError> { ) -> Result<Self, HollowGameError> {
let template = archive_battle_quest_id.template(); let template = archive_battle_quest_id.template();
let avatars = match avatars
.iter()
.map(|id| RobotConfigID::new(*id).map(|id| AvatarUnitID::Robot(id)))
.collect::<Result<Vec<_>, _>>()
{
Ok(avatars) => avatars,
Err(err) => return Err(HollowGameError::InvalidAvatarID(err.0)),
};
let buddy_params = match RobotBuddyConfigID::new(buddy_id) {
Ok(id) => vec![BuddyParam(BuddyUnitID::Robot(id), BuddyTeamType::Fighting)],
Err(_) => Vec::with_capacity(0),
};
Ok(Self { Ok(Self {
quest_id: template.id.value(), quest_id: template.id.value(),
battle_event_id: template.battle_event_id, battle_event_id: template.battle_event_id,
@ -100,7 +72,12 @@ impl HollowGame {
weather: WeatherType::SunShine, weather: WeatherType::SunShine,
start_timestamp: util::cur_timestamp() as i64, start_timestamp: util::cur_timestamp() as i64,
play_type, play_type,
team_data: TeamDataItem::new(&avatars, &buddy_params), team_data: TeamDataItem::new(
avatars,
&(buddy_id != 0)
.then_some(vec![BuddyParam(buddy_id, BuddyTeamType::Fighting)])
.unwrap_or_default(),
),
fight_drop_pool: FightDropPool::new(template.battle_event_id), fight_drop_pool: FightDropPool::new(template.battle_event_id),
quest_manager: DungeonQuestManager::default(), quest_manager: DungeonQuestManager::default(),
}) })
@ -127,20 +104,6 @@ impl HollowGame {
return Err(HollowGameError::BattleGroupNotFound(template.id.value())); return Err(HollowGameError::BattleGroupNotFound(template.id.value()));
}; };
let avatars = match avatars
.iter()
.map(|id| AvatarBaseID::new(*id).map(|id| AvatarUnitID::Base(id)))
.collect::<Result<Vec<_>, _>>()
{
Ok(avatars) => avatars,
Err(err) => return Err(HollowGameError::InvalidAvatarID(err.0)),
};
let buddy_params = match BuddyBaseID::new(buddy_id) {
Ok(id) => vec![BuddyParam(BuddyUnitID::Base(id), BuddyTeamType::Fighting)],
Err(_) => Vec::with_capacity(0),
};
Ok(Self { Ok(Self {
quest_id: template.id.value(), quest_id: template.id.value(),
battle_event_id: battle_group.battle_event_id, battle_event_id: battle_group.battle_event_id,
@ -150,7 +113,12 @@ impl HollowGame {
play_type: Self::get_play_type_by_quest_type(EHollowQuestType::from( play_type: Self::get_play_type_by_quest_type(EHollowQuestType::from(
template.hollow_quest_type, template.hollow_quest_type,
)), )),
team_data: TeamDataItem::new(&avatars, &buddy_params), team_data: TeamDataItem::new(
avatars,
&(buddy_id != 0)
.then_some(vec![BuddyParam(buddy_id, BuddyTeamType::Fighting)])
.unwrap_or_default(),
),
fight_drop_pool: FightDropPool::new(battle_group.battle_event_id), fight_drop_pool: FightDropPool::new(battle_group.battle_event_id),
quest_manager: DungeonQuestManager::new_for_battle_group(battle_group.id), quest_manager: DungeonQuestManager::new_for_battle_group(battle_group.id),
}) })

View file

@ -1,5 +1,5 @@
use common::util; use common::util;
use data::tables::{self, AvatarBaseID, BattleEventConfigID, BuddyBaseID, HollowQuestID}; use data::tables::{self, BattleEventConfigID, HollowQuestID};
use proto::{ use proto::{
DungeonInfo, DungeonItemData, FightQuestInfo, LongFightInfo, LongFightSceneInfo, SceneInfo, DungeonInfo, DungeonItemData, FightQuestInfo, LongFightInfo, LongFightSceneInfo, SceneInfo,
WeatherPoolInfo, WeatherPoolInfo,
@ -9,7 +9,7 @@ use thiserror::Error;
use crate::logic::{ use crate::logic::{
battle::{ battle::{
drop::FightDropPool, drop::FightDropPool,
unit::{AvatarUnit, AvatarUnitID, BuddyUnit, BuddyUnitID}, unit::{AvatarUnit, BuddyUnit},
BuddyParam, DungeonQuestManager, LogicVariableTable, TeamDataItem, BuddyParam, DungeonQuestManager, LogicVariableTable, TeamDataItem,
}, },
BuddyTeamType, EHollowQuestType, ELocalPlayType, ESceneType, TimePeriodType, WeatherType, BuddyTeamType, EHollowQuestType, ELocalPlayType, ESceneType, TimePeriodType, WeatherType,
@ -23,8 +23,6 @@ pub enum LongFightGameError {
InvalidQuestType(EHollowQuestType), InvalidQuestType(EHollowQuestType),
#[error("Battle group not found, quest id: {0}")] #[error("Battle group not found, quest id: {0}")]
BattleGroupNotFound(u32), BattleGroupNotFound(u32),
#[error("Invalid avatar id: {0}")]
InvalidAvatarID(u32),
} }
pub struct LongFightGame { pub struct LongFightGame {
@ -41,7 +39,7 @@ pub struct LongFightGame {
} }
impl LongFightGame { impl LongFightGame {
const RALLY_GUIDANCE_BUDDY: BuddyBaseID = BuddyBaseID::new_unchecked(50001); const RALLY_GUIDANCE_BUDDY_ID: u32 = 50001;
pub fn create_rally_game( pub fn create_rally_game(
quest_id: HollowQuestID, quest_id: HollowQuestID,
@ -63,25 +61,13 @@ impl LongFightGame {
return Err(LongFightGameError::BattleGroupNotFound(template.id.value())); return Err(LongFightGameError::BattleGroupNotFound(template.id.value()));
}; };
let avatars = match avatars
.iter()
.map(|id| AvatarBaseID::new(*id).map(|id| AvatarUnitID::Base(id)))
.collect::<Result<Vec<_>, _>>()
{
Ok(avatars) => avatars,
Err(err) => return Err(LongFightGameError::InvalidAvatarID(err.0)),
};
let mut buddy_params = vec![BuddyParam( let mut buddy_params = vec![BuddyParam(
BuddyUnitID::Base(Self::RALLY_GUIDANCE_BUDDY), Self::RALLY_GUIDANCE_BUDDY_ID,
BuddyTeamType::RallyGuidance, BuddyTeamType::RallyGuidance,
)]; )];
if let Ok(buddy_id) = BuddyBaseID::new(buddy_id) { if buddy_id != 0 {
buddy_params.push(BuddyParam( buddy_params.push(BuddyParam(buddy_id, BuddyTeamType::Fighting));
BuddyUnitID::Base(buddy_id),
BuddyTeamType::Fighting,
));
} }
Ok(Self { Ok(Self {
@ -91,7 +77,7 @@ impl LongFightGame {
time_period, time_period,
weather, weather,
start_timestamp: util::cur_timestamp() as i64, start_timestamp: util::cur_timestamp() as i64,
team_data: TeamDataItem::new(&avatars, &buddy_params), team_data: TeamDataItem::new(avatars, &buddy_params),
variable_table: LogicVariableTable::new(battle_group.battle_event_id), variable_table: LogicVariableTable::new(battle_group.battle_event_id),
fight_drop_pool: FightDropPool::new(battle_group.battle_event_id), fight_drop_pool: FightDropPool::new(battle_group.battle_event_id),
quest_manager: DungeonQuestManager::new_for_battle_group(battle_group.id), quest_manager: DungeonQuestManager::new_for_battle_group(battle_group.id),

View file

@ -2,7 +2,6 @@ mod fresh;
mod frontend; mod frontend;
mod hollow; mod hollow;
mod long_fight; mod long_fight;
use data::tables::TemplateNotFoundError;
pub use fresh::*; pub use fresh::*;
pub use frontend::*; pub use frontend::*;
pub use hollow::*; pub use hollow::*;
@ -37,8 +36,6 @@ pub enum LogicError {
LongFight(#[from] LongFightGameError), LongFight(#[from] LongFightGameError),
#[error("dungeon quest error: {0}")] #[error("dungeon quest error: {0}")]
DungeonQuest(#[from] DungeonQuestError), DungeonQuest(#[from] DungeonQuestError),
#[error("{0}")]
TemplateNotFound(#[from] TemplateNotFoundError),
} }
impl GameInstance { impl GameInstance {

View file

@ -53,14 +53,14 @@ impl BasicDataModel {
exp: bin.exp, exp: bin.exp,
profile_icon: bin.profile_icon, profile_icon: bin.profile_icon,
frontend_avatar_id: match bin.frontend_avatar_id { frontend_avatar_id: match bin.frontend_avatar_id {
1.. => AvatarBaseID::new(bin.frontend_avatar_id as u32).ok(), 1.. => AvatarBaseID::new(bin.frontend_avatar_id as u32),
_ => None, _ => None,
}, },
beginner_procedure_id: match bin.beginner_procedure_id { beginner_procedure_id: match bin.beginner_procedure_id {
1.. => ProcedureConfigID::new(bin.beginner_procedure_id as u32).ok(), 1.. => ProcedureConfigID::new(bin.beginner_procedure_id as u32),
_ => None, _ => None,
}, },
selected_post_girl_id: PostGirlConfigID::new(bin.selected_post_girl_id).ok(), selected_post_girl_id: PostGirlConfigID::new(bin.selected_post_girl_id),
nick_name: match bin.nick_name.is_empty() { nick_name: match bin.nick_name.is_empty() {
true => None, true => None,
false => Some(bin.nick_name), false => Some(bin.nick_name),
@ -84,7 +84,7 @@ impl BasicDataModel {
.unwrap_or(-1), .unwrap_or(-1),
selected_post_girl_id: match self.selected_post_girl_id { selected_post_girl_id: match self.selected_post_girl_id {
Some(post_girl_id) => post_girl_id.value(), Some(post_girl_id) => post_girl_id.value(),
None => 0, None => 0
}, },
} }
} }

View file

@ -15,7 +15,7 @@ impl LockModel {
unlock_list: bin unlock_list: bin
.unlock_list .unlock_list
.into_iter() .into_iter()
.map(|id| UnlockConfigID::new_unchecked(id as u32)) .map(UnlockConfigID::new_unchecked)
.collect(), .collect(),
quick_access_list: bin quick_access_list: bin
.quick_access_list .quick_access_list
@ -31,7 +31,7 @@ impl LockModel {
.unlock_list .unlock_list
.clone() .clone()
.into_iter() .into_iter()
.map(|i| i.value() as i32) .map(|i| i.value())
.collect(), .collect(),
quick_access_list: self quick_access_list: self
.quick_access_list .quick_access_list
@ -65,12 +65,13 @@ impl LockModel {
} }
pub fn to_client(&self) -> UnlockData { pub fn to_client(&self) -> UnlockData {
UnlockData { UnlockData {
unlock_id_list: self unlock_id_list: self
.unlock_list .unlock_list
.clone() .clone()
.into_iter() .into_iter()
.map(|i| i.value() as i32) .map(|i| i.value())
.collect(), .collect(),
quick_access_data_list: self.quick_access_to_client(), quick_access_data_list: self.quick_access_to_client(),
..Default::default() ..Default::default()
@ -85,10 +86,27 @@ impl LockModel {
self.unlock_list.contains(&id) self.unlock_list.contains(&id)
} }
pub fn mod_quick_access(&mut self, index: u32, id: Option<QuickFuncID>) { pub fn mod_quick_access(&mut self, index: u32, id: Option<QuickFuncID>) -> QuickAccessData {
match id { let btn_id = match id {
Some(quick_access_id) => self.quick_access_list.insert(index, quick_access_id), Some(quick_access_id) => {
None => self.quick_access_list.remove(&index), if self.quick_access_list.contains_key(&index) {
*self.quick_access_list.get_mut(&index).unwrap() = quick_access_id;
} else {
self.quick_access_list.insert(index, quick_access_id);
}
quick_access_id.value()
}
None => {
if self.quick_access_list.contains_key(&index) {
self.quick_access_list.remove(&index);
}
0
}
}; };
QuickAccessData {
r#type: QuickAccessType::QuickMenu.into(),
quick_access_index: index,
btn_id,
}
} }
} }

View file

@ -22,15 +22,13 @@ impl RoleModel {
const DEFAULT_AVATARS: [u32; 2] = [1011, 1081]; const DEFAULT_AVATARS: [u32; 2] = [1011, 1081];
pub fn add_avatar(&mut self, template_id: AvatarBaseID) { pub fn add_avatar(&mut self, template_id: AvatarBaseID) {
if !self.has_avatar(template_id) { if !self
self.avatar_list.push(Avatar::new(template_id)); .avatar_list
}
}
pub fn has_avatar(&self, template_id: AvatarBaseID) -> bool {
self.avatar_list
.iter() .iter()
.any(|a| a.template_id == template_id) .any(|a| a.template_id == template_id)
{
self.avatar_list.push(Avatar::new(template_id));
}
} }
pub fn avatar_sync(&self) -> AvatarSync { pub fn avatar_sync(&self) -> AvatarSync {

View file

@ -12,7 +12,7 @@ impl SceneUnitManager {
let unit_vec = tables::main_city_object_template_tb::iter() let unit_vec = tables::main_city_object_template_tb::iter()
.filter(|tmpl| tmpl.get_section_name() == section_template.section_name) .filter(|tmpl| tmpl.get_section_name() == section_template.section_name)
.filter(|tmpl| MainCityDefaultObjectID::new(tmpl.tag_id.value()).is_ok()) // check if npc tag present in default object table .filter(|tmpl| MainCityDefaultObjectID::new(tmpl.tag_id.value()).is_some()) // check if npc tag present in default object table
.map(|tmpl| SceneUnit::new(tmpl.tag_id)) .map(|tmpl| SceneUnit::new(tmpl.tag_id))
.collect(); .collect();