mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-07-04 14:03:33 +00:00
Compare commits
46 Commits
Author | SHA1 | Date | |
---|---|---|---|
8b83dbf58c | |||
d6fef3252f | |||
e73984bd41 | |||
553e22ead8 | |||
5878cb6f8d | |||
100d08ec5d | |||
83b84408a1 | |||
da3981089d | |||
ad502a8568 | |||
f6c84fdfbf | |||
1c4d263dd2 | |||
35962542af | |||
0b5329514b | |||
46b0c7cf93 | |||
1e932ce144 | |||
b1a9ed0226 | |||
676ed32a12 | |||
05fe62b49a | |||
b781e560e4 | |||
5c4c62c1ed | |||
e2b59fbd8d | |||
84bf783243 | |||
4d8caf5a8c | |||
a30f16b0e1 | |||
65915b7666 | |||
1ceda2a455 | |||
09f392bb5b | |||
944bfb76f3 | |||
dc7b8d8ca6 | |||
9f00ea3573 | |||
12316b36b1 | |||
0fb7d50acd | |||
c926fe326c | |||
e8930e92e1 | |||
4ed0b90c27 | |||
7bfb35ac39 | |||
47911aa16e | |||
855d3182ab | |||
43b7d7a383 | |||
55928d9154 | |||
6219902e0f | |||
d7af52f94b | |||
c21d216d8d | |||
60657b3b98 | |||
f07ce48b24 | |||
2dd644f28b |
2
.github/workflows/protect_files.yml
vendored
2
.github/workflows/protect_files.yml
vendored
@ -20,4 +20,4 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: superbrothers/close-pull-request@v3
|
- uses: superbrothers/close-pull-request@v3
|
||||||
with:
|
with:
|
||||||
comment: "This PR has been closed for modifying protected files. See `CONTIBUTING.md` for more information."
|
comment: "This PR has been closed for modifying protected files. See `CONTRIBUTING.md` for more information."
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**Attention:** We always welcome contributors to the project. Before adding your contribution, please carefully read our [Code of Conduct](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
**Attention:** We always welcome contributors to the project. Before adding your contribution, please carefully read our [Code of Conduct](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**תשומת לב בבקשה:** אנחנו מקבלים עזרה בפיתוח התוכנה. לפני שאתם תורמים לפרויקט בבקשה תקראו את [תנאי השימוש](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
**תשומת לב בבקשה:** אנחנו מקבלים עזרה בפיתוח התוכנה. לפני שאתם תורמים לפרויקט בבקשה תקראו את [תנאי השימוש](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**Aantekening:** We verwelkomen altijd bijdragers aan het project. Lees onze [Gedragscode](https://github.com/Grasscutters/Grasscutter/blob/development/README_NL.md#bijdragen-aan-het-project) zorgvuldig door voordat u uw bijdrage toevoegt.
|
**Aantekening:** We verwelkomen altijd bijdragers aan het project. Lees onze [Gedragscode](https://github.com/Grasscutters/Grasscutter/blob/development/README_NL.md#bijdragen-aan-het-project) zorgvuldig door voordat u uw bijdrage toevoegt.
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**Atención:** Siempre damos la bienvenida a contribuidores del proyecto. Antes de añadir tu contribución, por favor lee cuidadosamente nuestro [Código de conducta](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
**Atención:** Siempre damos la bienvenida a contribuidores del proyecto. Antes de añadir tu contribución, por favor lee cuidadosamente nuestro [Código de conducta](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
||||||
|
|
||||||
@ -67,7 +67,7 @@
|
|||||||
|
|
||||||
2. Establece el proxy de red a `127.0.0.1:8080` o el puerto de proxy que pusiste.
|
2. Establece el proxy de red a `127.0.0.1:8080` o el puerto de proxy que pusiste.
|
||||||
|
|
||||||
**también puedes usar `start.cmd` para iniciar el servidor y el servicio de proxy automáticamente, pero tienes que configurar el entorno JAVA_HOME**
|
**También puedes usar `start.cmd` para iniciar el servidor y el servicio de proxy automáticamente, pero tienes que configurar el entorno JAVA_HOME**
|
||||||
|
|
||||||
### Construcción
|
### Construcción
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**Atensyon:** Ang mga kontributor ay laging welcome sa proyektong ito. Bago mag-bigay ng kontribusyon, basahin muna ng mabuti ang [Code of Conduct](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
**Atensyon:** Ang mga kontributor ay laging welcome sa proyektong ito. Bago mag-bigay ng kontribusyon, basahin muna ng mabuti ang [Code of Conduct](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**Attention:** De nouveaux contributeurs sont toujours les bienvenus. Avant d'ajouter votre contribution, veuillez lire le [code de conduite](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
**Attention:** De nouveaux contributeurs sont toujours les bienvenus. Avant d'ajouter votre contribution, veuillez lire le [code de conduite](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**Perhatian:** Kami selalu menyambut kontributor untuk proyek ini. Sebelum menambahkan kontribusi Anda, harap baca [Kode Etik](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md) kami.
|
**Perhatian:** Kami selalu menyambut kontributor untuk proyek ini. Sebelum menambahkan kontribusi Anda, harap baca [Kode Etik](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md) kami.
|
||||||
|
|
||||||
@ -14,7 +14,7 @@
|
|||||||
* Daftar teman
|
* Daftar teman
|
||||||
* Teleportasi
|
* Teleportasi
|
||||||
* Sistem gacha
|
* Sistem gacha
|
||||||
* Co-op *sebahagian* berfungsi
|
* Co-op *sebagian* berfungsi
|
||||||
* Memunculkan monster melalui konsol
|
* Memunculkan monster melalui konsol
|
||||||
* Fitur inventaris (menerima item/karakter, meng-upgrade item/karakter, dll)
|
* Fitur inventaris (menerima item/karakter, meng-upgrade item/karakter, dll)
|
||||||
|
|
||||||
@ -53,9 +53,9 @@
|
|||||||
|
|
||||||
**Catatan:** Sertifikat CA biasanya disimpan di `%USERPROFILE%\ .mitmproxy`, atau anda dapat download dari `http://mitm.it`
|
**Catatan:** Sertifikat CA biasanya disimpan di `%USERPROFILE%\ .mitmproxy`, atau anda dapat download dari `http://mitm.it`
|
||||||
|
|
||||||
klik dua kali untuk [menginstall](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate) or ...
|
klik dua kali untuk [menginstall](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate) ataupun juga
|
||||||
|
|
||||||
- Via command line
|
- melalui command line
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
||||||
@ -103,6 +103,6 @@ Anda bisa menemukan output jar di root folder proyek.
|
|||||||
# Quick Troubleshooting
|
# Quick Troubleshooting
|
||||||
|
|
||||||
* Jika kompilasi tidak berhasil, periksa instalasi JDK Anda (JDK 17 dan validasi variabel bin PATH JDK)
|
* Jika kompilasi tidak berhasil, periksa instalasi JDK Anda (JDK 17 dan validasi variabel bin PATH JDK)
|
||||||
* Klien saya tidak terhubung, tidak login, 4206, dll... - Sebagian besar pengaturan daemon proxy Anda adalah *masalahnya*, jika menggunakan
|
* Klien saya tidak terhubung, tidak login, 4206, dan lain-lain - Sebagian besar pengaturan daemon proxy Anda adalah *masalahnya*, jika menggunakan
|
||||||
Fiddler pastikan berjalan pada port lain kecuali 8888
|
Fiddler pastikan berjalan pada port lain kecuali 8888
|
||||||
* Urutan startup: MongoDB > Grasscutter > Proxy daemon (mitmdump, fiddler, etc.) > Game
|
* Urutan startup: MongoDB > Grasscutter > Proxy daemon (mitmdump, fiddler, etc.) > Game
|
||||||
|
108
README_it-IT.md
Normal file
108
README_it-IT.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|

|
||||||
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
|
**Attenzione:** Diamo sempre il benvenuto ai contributori del progetto. Prima di aggiungere il tuo contributo, leggi attentamente il nostro [Codice di condotta](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
## Funzionalità attuali
|
||||||
|
|
||||||
|
* Login
|
||||||
|
* Combattimento
|
||||||
|
* Lista di amici
|
||||||
|
* Teletrasporto
|
||||||
|
* Sistema Gacha
|
||||||
|
* Cooperativa *parzialmente* funzionale
|
||||||
|
* Evoca mostri dalla console
|
||||||
|
* Funzionalità dell'inventario (ricevi oggetti/personaggi, aggiorna oggetti/personaggi, ecc.)
|
||||||
|
|
||||||
|
## Guida rapida all'installazione
|
||||||
|
|
||||||
|
**Nota:** Per il supporto, unisciti al nostro [Discord](https://discord.gg/T5vZU6UyeG).
|
||||||
|
|
||||||
|
### Requisiti
|
||||||
|
|
||||||
|
* Java SE - 17 ([link](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html))
|
||||||
|
|
||||||
|
**Nota:** se vuoi solo **eseguirlo**, **jre** è sufficiente.
|
||||||
|
|
||||||
|
* [MongoDB](https://www.mongodb.com/try/download/community) (consigliato 4.0+)
|
||||||
|
|
||||||
|
* Servizio proxy: mitmproxy (mitmdump, consigliato), Fiddler Classic, ecc.
|
||||||
|
|
||||||
|
### Esecuzione
|
||||||
|
|
||||||
|
**Nota:** Se hai eseguito l'aggiornamento da una versione precedente, rimuovi `config.json` in modo che venga generato di nuovo.
|
||||||
|
|
||||||
|
1. Ottieni "grasscutter.jar".
|
||||||
|
- Scarica da [azioni](https://github.com/Grasscutters/Grasscutter/suites/6895963598/artifacts/267483297)
|
||||||
|
- [Compilalo tu stesso](#Compilazione)
|
||||||
|
2. Crea una cartella `resources` nella directory in cui si trova grasscutter.jar e sposta lì le cartelle `BinOutput` ed `ExcelBinOutput` *(Vedi il [wiki](https://github.com/Grasscutters/Grasscutter/wiki ) per maggiori dettagli su come ottenerli.)*
|
||||||
|
3. Eseguire Grasscutter con `java -jar grasscutter.jar`. **Assicurati che il servizio mongodb sia attivo.**
|
||||||
|
|
||||||
|
### Connessione client
|
||||||
|
|
||||||
|
½. Crea un account usando [il comando corrispondente nella console del server](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting).
|
||||||
|
|
||||||
|
1. Reindirizza il traffico: (scegli uno)
|
||||||
|
- mitmdump: `mitmdump -s proxy.py -k`
|
||||||
|
|
||||||
|
Autorizza il certificato CA:
|
||||||
|
|
||||||
|
**Nota:**Il certificato CA si trova solitamente in `%USERPROFILE%\ .mitmproxy`, oppure puoi scaricarlo da `http://mitm.it`
|
||||||
|
|
||||||
|
Fare doppio clic su [installa](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate) o ...
|
||||||
|
|
||||||
|
- Con riga di comando
|
||||||
|
|
||||||
|
```shell
|
||||||
|
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
||||||
|
```
|
||||||
|
|
||||||
|
- Fiddler Classic: esegui Fiddler Classic, abilita `Decrypt https traffic` nelle opzioni e cambia la porta predefinita in (Strumenti -> Opzioni -> Connessioni) in qualcosa di diverso da `8888`, e carica [questo script](https :/ /github.lunatic.moe/fiddlerscript).
|
||||||
|
|
||||||
|
- [File host](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
|
||||||
|
|
||||||
|
2. Impostare il proxy di rete su `127.0.0.1:8080` o la porta proxy impostata.
|
||||||
|
|
||||||
|
**Puoi anche usare `start.cmd` per avviare automaticamente il server e il servizio proxy, ma devi impostare l'ambiente JAVA_HOME**
|
||||||
|
|
||||||
|
### Compilazione
|
||||||
|
|
||||||
|
Grasscutter usa Gradle per gestire le dipendenze e le build.
|
||||||
|
|
||||||
|
**Requisiti:**
|
||||||
|
|
||||||
|
- [Kit di sviluppo Java SE - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
||||||
|
- [Git](https://git-scm.com/downloads)
|
||||||
|
|
||||||
|
##### Windows
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/Grasscutters/Grasscutter.git
|
||||||
|
cd grasscutter
|
||||||
|
.\gradlew.bat # Impostazioni dell'ambiente
|
||||||
|
.\gradlew jar # Compila
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Linux
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/Grasscutters/Grasscutter.git
|
||||||
|
cd grasscutter
|
||||||
|
chmod +x gradlew
|
||||||
|
./gradlew jar # Compila
|
||||||
|
```
|
||||||
|
|
||||||
|
Puoi trovare il jar generato nella cartella principale del progetto.
|
||||||
|
|
||||||
|
### I comandi sono stati spostati nel [wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands)!
|
||||||
|
|
||||||
|
# Soluzioni agli errori comuni
|
||||||
|
|
||||||
|
* Se la compilazione non riesce, controlla l'installazione di JDK (JDK 17 e convalida la variabile JDK bin PATH)
|
||||||
|
* Il mio client non si connette, non accede, 4206, ecc... - Probabilmente le tue impostazioni proxy sono *il problema*, se usi
|
||||||
|
Fiddler assicurati di utilizzare una porta diversa da 8888
|
||||||
|
* Sequenza di avvio: MongoDB > Grasscutter > Servizio proxy (mitmdump, fiddler, ecc.) > Gioco
|
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
|
|
||||||
***:** 私たちはプロジェクトへの貢献者をいつでも歓迎します。 貢献を追加する前に、我々の [行動規範](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)をよくお読みください.
|
***:** 私たちはプロジェクトへの貢献者をいつでも歓迎します。貢献を追加する前に、我々の [行動規範](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)をよくお読みください。
|
||||||
|
|
||||||
## 現在機能している物
|
## 現在機能している物
|
||||||
|
|
||||||
@ -21,39 +21,37 @@
|
|||||||
|
|
||||||
## クイックセットアップガイド
|
## クイックセットアップガイド
|
||||||
|
|
||||||
***:** サポートが必要な場合はGrasscutterの[Discord](https://discord.gg/T5vZU6UyeG)に参加してください.
|
***:** サポートが必要な場合はGrasscutterの[Discord](https://discord.gg/T5vZU6UyeG)に参加してください。
|
||||||
|
|
||||||
### 動作環境
|
### 動作環境
|
||||||
|
|
||||||
* [JAVAのバージョン17以降](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
* [JAVAのバージョン17以降](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
||||||
|
|
||||||
***:** サーバーを動作させるだけならjreのみで十分です。 開発をしたい場合JDKが必要になるかもしれません。
|
***:** サーバーを動作させるだけならjreのみで十分です。 開発をしたい場合JDKが必要になるかもしれません。
|
||||||
|
|
||||||
* [MongoDB](https://www.mongodb.com/try/download/community) (バージョン4.0以降を推奨)
|
* [MongoDB](https://www.mongodb.com/try/download/community) (バージョン4.0以降を推奨)
|
||||||
|
|
||||||
* プロキシツール: [mitmproxy](https://mitmproxy.org/) (mitmdump, 推奨)、 [Fiddler Classic](https://telerik-fiddler.s3.amazonaws.com/fiddler/FiddlerSetup.exe)、 その他。
|
* プロキシツール: [mitmproxy](https://mitmproxy.org/) (mitmdump, 推奨)、[Fiddler Classic](https://telerik-fiddler.s3.amazonaws.com/fiddler/FiddlerSetup.exe)、その他。
|
||||||
|
|
||||||
### 起動方法
|
### 起動方法
|
||||||
|
|
||||||
***:** もしサーバーをアップデートしたい場合は`config.json`を削除してから再生成してください。
|
***:** もしサーバーをアップデートしたい場合は`config.json`を削除してから再生成してください。
|
||||||
|
|
||||||
1. `grasscutter.jar`を入手する
|
1. `grasscutter.jar`を入手する
|
||||||
- [action](https://github.com/Grasscutters/Grasscutter/actions) からダウンロードするか [自分でビルド](https://github.com/Grasscutters/Grasscutter#building)してください。
|
- [releases](https://github.com/Grasscutters/Grasscutter/releases/latest) か [action](https://github.com/Grasscutters/Grasscutter/actions) からダウンロードするか、[自分でビルド](https://github.com/Grasscutters/Grasscutter#building)してください。
|
||||||
2. `grasscutter.jar` があるディレクトリに `resources` フォルダーを作成しそこに `BinOutput, ExcelBinOutput, Readables, Scripts, Subtitle, TextMap` を移動してください *(`resources` フォルダの中身の入手方法については [wiki](https://github.com/Grasscutters/Grasscutter/wiki) を参照してください.)*
|
2. `grasscutter.jar` があるディレクトリに `resources` フォルダーを作成し、そこに `BinOutput, ExcelBinOutput, Readables, Scripts, Subtitle, TextMap` を移動してください *(`resources` フォルダの中身の入手方法については [wiki](https://github.com/Grasscutters/Grasscutter/wiki) を参照してください.)*
|
||||||
3. コマンドプロンプトに`java -jar grasscutter.jar`を入力しGrasscutterを起動してください。 **このときMongoDBも実行する必要があります。**
|
3. コマンドプロンプトに`java -jar grasscutter.jar`を入力しGrasscutterを起動してください。**このときMongoDBも実行する必要があります。**
|
||||||
|
|
||||||
### クライアントとの接続
|
### クライアントとの接続
|
||||||
|
|
||||||
½. [サーバーコンソールコマンド](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting)を使用してアカウントを作成してください。
|
½. [このコマンド](https://github.com/Grasscutters/Grasscutter/wiki/Commands#commands-for-server-admins)をサーバーコンソールから使用してアカウントを作成してください。
|
||||||
|
|
||||||
1. 通信内容をリダイレクトする: (どちらか一つを選択してください)
|
1. 通信内容をリダイレクトする: (どちらか一つを選択してください)
|
||||||
- mitmdump: `mitmdump -s proxy.py -k`
|
- mitmdump: `mitmdump -s proxy.py -k`
|
||||||
|
|
||||||
CA証明書を信頼する:
|
- CA証明書を信頼する:
|
||||||
|
|
||||||
***:** CA証明書は`%USERPROFILE%\.mitmproxy`に保存されているか、`http://mitm.it`からダウンロードできます。
|
- ***:** CA証明書は`%USERPROFILE%\.mitmproxy`に保存されています。ダブルクリックして[インストール](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate)するか...
|
||||||
|
|
||||||
ダブルクリックして[インストール](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate)するか...
|
|
||||||
|
|
||||||
- コマンドライン経由でインストールします
|
- コマンドライン経由でインストールします
|
||||||
|
|
||||||
@ -61,13 +59,14 @@
|
|||||||
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
||||||
```
|
```
|
||||||
|
|
||||||
- Fiddler Classic: Fiddler Classicを起動し設定から`Decrypt https traffic`をオンにしてください。 (Tools -> Options -> Connections) に有るポート番号の設定を`8888`以外に設定してください、その後この[スクリプト](https://github.com/Grasscutters/Grasscutter/wiki/Resources#fiddler-classic-jscript)をロードします。
|
- Fiddler Classic: Fiddler Classicを起動し(Tools -> Options -> HTTPS)から`Decrypt https traffic`をオンにしてください。 (Tools -> Options -> Connections) に有るポート番号の設定を`8888`以外に設定してください。その後この[スクリプト](https://github.com/Grasscutters/Grasscutter/wiki/Resources#fiddler-classic-jscript)をFiddlerScriptタブにコピペしてロードします。
|
||||||
|
|
||||||
- [ホストファイル](https://github.com/Grasscutters/Grasscutter/wiki/Resources#hosts-file)
|
- [ホストファイル](https://github.com/Grasscutters/Grasscutter/wiki/Resources#hosts-file)
|
||||||
|
|
||||||
2. ネットワークプロキシを `127.0.0.1:(自分で設定したポート番号)` に設定してください。
|
2. ネットワークプロキシを `127.0.0.1:(自分で設定したポート番号)` に設定してください。
|
||||||
|
- mitmproxyを使用した場合:プロキシの設定と証明書のインストールが終わった後、http://mitm.it/ でトラフィックがmitmproxyを通過しているか確認しましょう。
|
||||||
|
|
||||||
**`start_config.cmd`でJAVAのパスを指定している必要があります。 `start.cmd`でmitmdumpとサーバーをまとめて起動することが出来ます。**
|
**`start.cmd`でmitmdumpとサーバーをまとめて起動することが出来ます。ただ、事前に`start_config.cmd`でJAVAのパスを指定している必要があります。**
|
||||||
|
|
||||||
### ビルド
|
### ビルド
|
||||||
|
|
||||||
@ -75,7 +74,7 @@ GrasscutterはGradleを使用して依存関係とビルドを処理していま
|
|||||||
|
|
||||||
**要件:**
|
**要件:**
|
||||||
|
|
||||||
- [Java SE 開発キット - 17以降](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
- [Java SE Development Kits - 17以降](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
||||||
- [Git](https://git-scm.com/downloads)
|
- [Git](https://git-scm.com/downloads)
|
||||||
|
|
||||||
##### Windows
|
##### Windows
|
||||||
@ -96,13 +95,13 @@ chmod +x gradlew
|
|||||||
./gradlew jar # コンパイル
|
./gradlew jar # コンパイル
|
||||||
```
|
```
|
||||||
|
|
||||||
コンパイルされたjarファイルはプロゼクトフォルダーのルートに有ります。
|
生成されたjarファイルはプロジェクトフォルダのルートに有ります。
|
||||||
|
|
||||||
### コマンドリストは[wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands)へ移動しました。
|
### コマンドリストは[wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands)へ移動しました。
|
||||||
|
|
||||||
# トラブルシューティング
|
# トラブルシューティング
|
||||||
|
|
||||||
* コンパイルが失敗した場合JDKがインストールされているか確認してください (JDKの17以降と環境変数でJAVAのパスが設定されている必要があります)
|
* コンパイルが失敗した場合JDKがインストールされているか確認してください。(JDKのバージョンが17以降であることと、環境変数でJDKのパスが設定されている必要があります)
|
||||||
* クライアントが接続できない、 ログインできない、 エラーコード4206、 その他... - ほとんどの場合、プロキシ デーモンの設定が問題です。
|
* クライアントが接続できない・ログインできない・エラーコード4206・またその他場合、ほとんどは、プロキシデーモンの設定が問題です。Fiddlerを使っている場合はデフォルトポートを8888以外の別のポートに変更してみてください。
|
||||||
Fiddlerを使用している場合はポートが8888以外に設定されていることを確認してください。
|
Fiddlerを使用している場合はポートが8888以外に設定されていることを確認してください。
|
||||||
* 起動シーケンス(順番): MongoDB > Grasscutter > プロキシツール (mitmdumpかfiddler、その他) > ゲーム
|
* 起動シーケンス(順番): MongoDB > Grasscutter > プロキシツール (mitmdumpかfiddler、その他) > ゲーム
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**주의 :** 우리는 항상 프로젝트에 기여하는 사람들을 환영합니다. 기여를 하기 전, [행동 지침](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)을 주의 깊게 읽어주세요.
|
**주의 :** 우리는 항상 프로젝트에 기여하는 사람들을 환영합니다. 기여를 하기 전, [행동 지침](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)을 주의 깊게 읽어주세요.
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**Uwaga:** Zawsze jesteśmy otwarci na wasz wkład w projekt. Przed zaproponowaniem zmian przeczytaj [zasady postępowania (ENG)](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
**Uwaga:** Zawsze jesteśmy otwarci na wasz wkład w projekt. Przed zaproponowaniem zmian przeczytaj [zasady postępowania (ENG)](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**Внимание:** Мы всегда рады новому вкладу в проект. Однако, перед тем, как сделать свой вклад, пожалуйста, прочтите наш [кодекс делового поведения](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
**Внимание:** Мы всегда рады новому вкладу в проект. Однако, перед тем, как сделать свой вклад, пожалуйста, прочтите наш [кодекс делового поведения](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**请注意:** 欢迎成为本项目的贡献者。但在提交 PR 之前, 请仔细阅读 [代码规范](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。
|
**请注意:** 欢迎成为本项目的贡献者。但在提交 PR 之前, 请仔细阅读 [代码规范](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md)
|
[EN](README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md)
|
||||||
|
|
||||||
**請注意:** 歡迎成為本專案的貢獻者。在提交 PR 之前, 請仔細閱讀[程式碼規範](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。
|
**請注意:** 歡迎成為本專案的貢獻者。在提交 PR 之前, 請仔細閱讀[程式碼規範](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ sourceCompatibility = JavaVersion.VERSION_17
|
|||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
|
||||||
group = 'xyz.grasscutters'
|
group = 'xyz.grasscutters'
|
||||||
version = '1.4.2'
|
version = '1.4.4-dev'
|
||||||
|
|
||||||
sourceCompatibility = 17
|
sourceCompatibility = 17
|
||||||
targetCompatibility = 17
|
targetCompatibility = 17
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
270
gradlew
vendored
270
gradlew
vendored
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2015 the original author or authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -17,78 +17,113 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
#
|
||||||
## Gradle start up script for UN*X
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
##
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
PRG="$0"
|
app_path=$0
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
# Need this for daisy-chained symlinks.
|
||||||
ls=`ls -ld "$PRG"`
|
while
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
[ -h "$app_path" ]
|
||||||
PRG="$link"
|
do
|
||||||
else
|
ls=$( ls -ld "$app_path" )
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
link=${ls#*' -> '}
|
||||||
fi
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=${0##*/}
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "`uname`" in
|
case "$( uname )" in #(
|
||||||
CYGWIN* )
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
cygwin=true
|
Darwin* ) darwin=true ;; #(
|
||||||
;;
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
Darwin* )
|
NONSTOP* ) nonstop=true ;;
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
@ -105,84 +140,95 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
case $MAX_FD in #(
|
||||||
if [ $? -eq 0 ] ; then
|
max*)
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
warn "Could not query maximum file descriptor limit"
|
||||||
fi
|
esac
|
||||||
ulimit -n $MAX_FD
|
case $MAX_FD in #(
|
||||||
if [ $? -ne 0 ] ; then
|
'' | soft) :;; #(
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
*)
|
||||||
fi
|
ulimit -n "$MAX_FD" ||
|
||||||
else
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=$((i+1))
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
(0) set -- ;;
|
|
||||||
(1) set -- "$args0" ;;
|
|
||||||
(2) set -- "$args0" "$args1" ;;
|
|
||||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
save () {
|
# * args from the command line
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
# * the main class name
|
||||||
echo " "
|
# * -classpath
|
||||||
}
|
# * -D...appname settings
|
||||||
APP_ARGS=$(save "$@")
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
|
||||||
cd "$(dirname "$0")"
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command;
|
||||||
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
# double quotes to make sure that they get re-expanded; and
|
||||||
|
# * put everything else in single quotes, so that it's not re-expanded.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
2
gradlew-jar.bat
Normal file
2
gradlew-jar.bat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
call .\gradlew jar
|
||||||
|
pause
|
25
gradlew.bat
vendored
25
gradlew.bat
vendored
@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
|||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto init
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@ -51,7 +54,7 @@ goto fail
|
|||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto init
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
@ -61,28 +64,14 @@ echo location of your Java installation.
|
|||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:init
|
|
||||||
@rem Get command-line arguments, handling Windows variants
|
|
||||||
|
|
||||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
|
||||||
|
|
||||||
:win9xME_args
|
|
||||||
@rem Slurp the command line arguments.
|
|
||||||
set CMD_LINE_ARGS=
|
|
||||||
set _SKIP=2
|
|
||||||
|
|
||||||
:win9xME_args_slurp
|
|
||||||
if "x%~1" == "x" goto execute
|
|
||||||
|
|
||||||
set CMD_LINE_ARGS=%*
|
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute Gradle
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
@ -6,7 +6,7 @@ import emu.grasscutter.utils.Position;
|
|||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
|
|
||||||
public final class GameConstants {
|
public final class GameConstants {
|
||||||
public static String VERSION = "3.1.0";
|
public static String VERSION = "3.2.0";
|
||||||
|
|
||||||
public static final int DEFAULT_TEAMS = 4;
|
public static final int DEFAULT_TEAMS = 4;
|
||||||
public static final int MAX_TEAMS = 10;
|
public static final int MAX_TEAMS = 10;
|
||||||
|
@ -293,8 +293,8 @@ public final class Grasscutter {
|
|||||||
Grasscutter.getLogger().info("EOF detected.");
|
Grasscutter.getLogger().info("EOF detected.");
|
||||||
continue;
|
continue;
|
||||||
} catch (IOError e) {
|
} catch (IOError e) {
|
||||||
Grasscutter.getLogger().error("An IO error occurred.", e);
|
Grasscutter.getLogger().error("An IO error occurred while trying to read from console.", e);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
isLastInterrupted = false;
|
isLastInterrupted = false;
|
||||||
|
@ -33,21 +33,18 @@ public class CommandHelpers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static <T> List<String> parseIntParameters(List<String> args, @Nonnull T params, Map<Pattern, BiConsumer<T, Integer>> map) {
|
public static <T> List<String> parseIntParameters(List<String> args, @Nonnull T params, Map<Pattern, BiConsumer<T, Integer>> map) {
|
||||||
for (int i = args.size() - 1; i >= 0; i--) {
|
args.removeIf(arg -> {
|
||||||
String arg = args.get(i).toLowerCase();
|
var argL = arg.toLowerCase();
|
||||||
boolean deleteArg = false;
|
boolean deleteArg = false;
|
||||||
int argNum;
|
|
||||||
for (var entry : map.entrySet()) {
|
for (var entry : map.entrySet()) {
|
||||||
if ((argNum = matchIntOrNeg(entry.getKey(), arg)) != -1) {
|
int argNum = matchIntOrNeg(entry.getKey(), argL);
|
||||||
|
if (argNum != -1) {
|
||||||
entry.getValue().accept(params, argNum);
|
entry.getValue().accept(params, argNum);
|
||||||
deleteArg = true;
|
deleteArg = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (deleteArg) {
|
|
||||||
args.remove(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return deleteArg;
|
||||||
|
});
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ public final class CommandMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Command> getAnnotationsAsList() {
|
public List<Command> getAnnotationsAsList() {
|
||||||
return new LinkedList<>(this.annotations.values());
|
return new ArrayList<>(this.annotations.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Command> getAnnotations() {
|
public Map<String, Command> getAnnotations() {
|
||||||
@ -102,7 +102,7 @@ public final class CommandMap {
|
|||||||
* @return All command handlers as a list.
|
* @return All command handlers as a list.
|
||||||
*/
|
*/
|
||||||
public List<CommandHandler> getHandlersAsList() {
|
public List<CommandHandler> getHandlersAsList() {
|
||||||
return new LinkedList<>(this.commands.values());
|
return new ArrayList<>(this.commands.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, CommandHandler> getHandlers() {
|
public Map<String, CommandHandler> getHandlers() {
|
||||||
@ -234,8 +234,8 @@ public final class CommandMap {
|
|||||||
|
|
||||||
// Parse message.
|
// Parse message.
|
||||||
String[] split = rawMessage.split(" ");
|
String[] split = rawMessage.split(" ");
|
||||||
List<String> args = new LinkedList<>(Arrays.asList(split));
|
String label = split[0].toLowerCase();
|
||||||
String label = args.remove(0).toLowerCase();
|
List<String> args = new ArrayList<>(Arrays.asList(split).subList(1, split.length));
|
||||||
String playerId = (player == null) ? consoleId : player.getAccount().getId();
|
String playerId = (player == null) ? consoleId : player.getAccount().getId();
|
||||||
|
|
||||||
// Check for special cases - currently only target command.
|
// Check for special cases - currently only target command.
|
||||||
|
@ -9,6 +9,7 @@ import emu.grasscutter.game.player.Player;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static emu.grasscutter.utils.Language.translate;
|
import static emu.grasscutter.utils.Language.translate;
|
||||||
|
|
||||||
@ -78,9 +79,10 @@ public final class SendMailCommand implements CommandHandler {
|
|||||||
Grasscutter.getGameServer().getPlayerByUid(mailBuilder.recipient, true).sendMail(mailBuilder.mail);
|
Grasscutter.getGameServer().getPlayerByUid(mailBuilder.recipient, true).sendMail(mailBuilder.mail);
|
||||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.send_done", mailBuilder.recipient));
|
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.send_done", mailBuilder.recipient));
|
||||||
} else {
|
} else {
|
||||||
for (Player player : DatabaseHelper.getAllPlayers()) {
|
DatabaseHelper.getByGameClass(Player.class).forEach(player -> {
|
||||||
Grasscutter.getGameServer().getPlayerByUid(player.getUid(), true).sendMail(mailBuilder.mail);
|
var onlinePlayer = Grasscutter.getGameServer().getPlayerByUid(player.getUid(), false);
|
||||||
}
|
Objects.requireNonNullElse(onlinePlayer, player).sendMail(mailBuilder.mail);
|
||||||
|
});
|
||||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.send_all_done"));
|
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.send_all_done"));
|
||||||
}
|
}
|
||||||
mailBeingConstructed.remove(senderId);
|
mailBeingConstructed.remove(senderId);
|
||||||
|
@ -67,9 +67,10 @@ public final class SetStatsCommand implements CommandHandler {
|
|||||||
|
|
||||||
// Compatibility aliases
|
// Compatibility aliases
|
||||||
this.stats.put("mhp", this.stats.get("maxhp"));
|
this.stats.put("mhp", this.stats.get("maxhp"));
|
||||||
this.stats.put("hp", new Stat(FightProperty.FIGHT_PROP_CUR_HP)); // Overrides FIGHT_PROP_HP
|
this.stats.put("hp", this.stats.get("_cur_hp")); // Overrides FIGHT_PROP_HP
|
||||||
this.stats.put("atk", new Stat(FightProperty.FIGHT_PROP_CUR_ATTACK)); // Overrides FIGHT_PROP_ATTACK
|
this.stats.put("atk", this.stats.get("_cur_attack")); // Overrides FIGHT_PROP_ATTACK
|
||||||
this.stats.put("atkb", new Stat(FightProperty.FIGHT_PROP_BASE_ATTACK)); // This doesn't seem to get used to recalculate ATK, so it's only useful for stuff like Bennett's buff.
|
this.stats.put("def", this.stats.get("_cur_defense")); // Overrides FIGHT_PROP_DEFENSE
|
||||||
|
this.stats.put("atkb", this.stats.get("_base_attack")); // This doesn't seem to get used to recalculate ATK, so it's only useful for stuff like Bennett's buff.
|
||||||
this.stats.put("eanemo", this.stats.get("anemo%"));
|
this.stats.put("eanemo", this.stats.get("anemo%"));
|
||||||
this.stats.put("ecryo", this.stats.get("cryo%"));
|
this.stats.put("ecryo", this.stats.get("cryo%"));
|
||||||
this.stats.put("edendro", this.stats.get("dendro%"));
|
this.stats.put("edendro", this.stats.get("dendro%"));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package emu.grasscutter.config;
|
package emu.grasscutter.config;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.Level;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||||
@ -101,6 +102,7 @@ public class ConfigContainer {
|
|||||||
public Game game = new Game();
|
public Game game = new Game();
|
||||||
|
|
||||||
public Dispatch dispatch = new Dispatch();
|
public Dispatch dispatch = new Dispatch();
|
||||||
|
public DebugMode debugMode = new DebugMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Language {
|
public static class Language {
|
||||||
@ -150,6 +152,10 @@ public class ConfigContainer {
|
|||||||
public int kcpInterval = 20;
|
public int kcpInterval = 20;
|
||||||
/* Controls whether packets should be logged in console or not */
|
/* Controls whether packets should be logged in console or not */
|
||||||
public ServerDebugMode logPackets = ServerDebugMode.NONE;
|
public ServerDebugMode logPackets = ServerDebugMode.NONE;
|
||||||
|
/* Show packet payload in console or no (in any case the payload is shown in encrypted view) */
|
||||||
|
public Boolean isShowPacketPayload = false;
|
||||||
|
/* Show annoying loop packets or no */
|
||||||
|
public Boolean isShowLoopPackets = false;
|
||||||
|
|
||||||
public GameOptions gameOptions = new GameOptions();
|
public GameOptions gameOptions = new GameOptions();
|
||||||
public JoinOptions joinOptions = new JoinOptions();
|
public JoinOptions joinOptions = new JoinOptions();
|
||||||
@ -163,9 +169,33 @@ public class ConfigContainer {
|
|||||||
|
|
||||||
public String defaultName = "Grasscutter";
|
public String defaultName = "Grasscutter";
|
||||||
|
|
||||||
|
/* Controls whether http requests should be logged in console or not */
|
||||||
public ServerDebugMode logRequests = ServerDebugMode.NONE;
|
public ServerDebugMode logRequests = ServerDebugMode.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Debug options container, used when jar launch argument is -debug | -debugall and override default values
|
||||||
|
* (see StartupArguments.enableDebug) */
|
||||||
|
public static class DebugMode {
|
||||||
|
/* Log level of the main server code (works only with -debug arg) */
|
||||||
|
public Level serverLoggerLevel = Level.DEBUG;
|
||||||
|
|
||||||
|
/* Log level of the third-party services (works only with -debug arg):
|
||||||
|
javalin, quartz, reflections, jetty, mongodb.driver*/
|
||||||
|
public Level servicesLoggersLevel = Level.INFO;
|
||||||
|
|
||||||
|
/* Controls whether packets should be logged in console or not */
|
||||||
|
public ServerDebugMode logPackets = ServerDebugMode.ALL;
|
||||||
|
|
||||||
|
/* Show packet payload in console or no (in any case the payload is shown in encrypted view) */
|
||||||
|
public Boolean isShowPacketPayload = false;
|
||||||
|
|
||||||
|
/* Show annoying loop packets or no */
|
||||||
|
public Boolean isShowLoopPackets = false;
|
||||||
|
|
||||||
|
/* Controls whether http requests should be logged in console or not */
|
||||||
|
public ServerDebugMode logRequests = ServerDebugMode.ALL;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Encryption {
|
public static class Encryption {
|
||||||
public boolean useEncryption = true;
|
public boolean useEncryption = true;
|
||||||
/* Should 'https' be appended to URLs? */
|
/* Should 'https' be appended to URLs? */
|
||||||
|
@ -38,6 +38,7 @@ public final class Configuration extends ConfigContainer {
|
|||||||
public static final HTTP HTTP_INFO = config.server.http;
|
public static final HTTP HTTP_INFO = config.server.http;
|
||||||
public static final Game GAME_INFO = config.server.game;
|
public static final Game GAME_INFO = config.server.game;
|
||||||
public static final Dispatch DISPATCH_INFO = config.server.dispatch;
|
public static final Dispatch DISPATCH_INFO = config.server.dispatch;
|
||||||
|
public static final DebugMode DEBUG_MODE_INFO = config.server.debugMode;
|
||||||
|
|
||||||
public static final Encryption HTTP_ENCRYPTION = config.server.http.encryption;
|
public static final Encryption HTTP_ENCRYPTION = config.server.http.encryption;
|
||||||
public static final Policies HTTP_POLICIES = config.server.http.policies;
|
public static final Policies HTTP_POLICIES = config.server.http.policies;
|
||||||
|
@ -5,6 +5,8 @@ import emu.grasscutter.server.http.handlers.GachaHandler;
|
|||||||
import emu.grasscutter.tools.Tools;
|
import emu.grasscutter.tools.Tools;
|
||||||
import emu.grasscutter.utils.FileUtils;
|
import emu.grasscutter.utils.FileUtils;
|
||||||
import emu.grasscutter.utils.JsonUtils;
|
import emu.grasscutter.utils.JsonUtils;
|
||||||
|
import emu.grasscutter.utils.TsvUtils;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -88,6 +90,17 @@ public class DataLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> loadTableToList(String resourcePath, Class<T> classType) throws IOException {
|
||||||
|
val path = FileUtils.getDataPathTsjJsonTsv(resourcePath);
|
||||||
|
Grasscutter.getLogger().info("Loading data table from: "+path);
|
||||||
|
return switch (FileUtils.getFileExtension(path)) {
|
||||||
|
case "json" -> JsonUtils.loadToList(path, classType);
|
||||||
|
case "tsj" -> TsvUtils.loadTsjToListSetField(path, classType);
|
||||||
|
case "tsv" -> TsvUtils.loadTsvToListSetField(path, classType);
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static void checkAllFiles() {
|
public static void checkAllFiles() {
|
||||||
try {
|
try {
|
||||||
List<Path> filenames = FileUtils.getPathsFromResource("/defaults/data/");
|
List<Path> filenames = FileUtils.getPathsFromResource("/defaults/data/");
|
||||||
|
@ -11,7 +11,10 @@ import emu.grasscutter.game.world.SpawnDataEntry;
|
|||||||
import emu.grasscutter.game.world.SpawnDataEntry.GridBlockId;
|
import emu.grasscutter.game.world.SpawnDataEntry.GridBlockId;
|
||||||
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
||||||
import emu.grasscutter.scripts.SceneIndexManager;
|
import emu.grasscutter.scripts.SceneIndexManager;
|
||||||
|
import emu.grasscutter.utils.FileUtils;
|
||||||
import emu.grasscutter.utils.JsonUtils;
|
import emu.grasscutter.utils.JsonUtils;
|
||||||
|
import emu.grasscutter.utils.TsvUtils;
|
||||||
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArraySet;
|
import it.unimi.dsi.fastutil.ints.IntArraySet;
|
||||||
@ -23,6 +26,8 @@ import java.io.*;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -32,8 +37,9 @@ import static emu.grasscutter.utils.Language.translate;
|
|||||||
|
|
||||||
public class ResourceLoader {
|
public class ResourceLoader {
|
||||||
|
|
||||||
private static final List<String> loadedResources = new ArrayList<>();
|
private static final Set<String> loadedResources = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
|
// Get a list of all resource classes, sorted by loadPriority
|
||||||
public static List<Class<?>> getResourceDefClasses() {
|
public static List<Class<?>> getResourceDefClasses() {
|
||||||
Reflections reflections = new Reflections(ResourceLoader.class.getPackage().getName());
|
Reflections reflections = new Reflections(ResourceLoader.class.getPackage().getName());
|
||||||
Set<?> classes = reflections.getSubTypesOf(GameResource.class);
|
Set<?> classes = reflections.getSubTypesOf(GameResource.class);
|
||||||
@ -51,6 +57,25 @@ public class ResourceLoader {
|
|||||||
return classList;
|
return classList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get a list containing sets of all resource classes, sorted by loadPriority
|
||||||
|
protected static List<Set<Class<?>>> getResourceDefClassesPrioritySets() {
|
||||||
|
val reflections = new Reflections(ResourceLoader.class.getPackage().getName());
|
||||||
|
val classes = reflections.getSubTypesOf(GameResource.class);
|
||||||
|
val priorities = ResourceType.LoadPriority.getInOrder();
|
||||||
|
Grasscutter.getLogger().debug("Priorities are "+priorities);
|
||||||
|
val map = new LinkedHashMap<ResourceType.LoadPriority, Set<Class<?>>>(priorities.size());
|
||||||
|
priorities.forEach(p -> map.put(p, new HashSet<>()));
|
||||||
|
|
||||||
|
classes.forEach(c -> {
|
||||||
|
// val c = (Class<?>) o;
|
||||||
|
val annotation = c.getAnnotation(ResourceType.class);
|
||||||
|
if (annotation != null) {
|
||||||
|
map.get(annotation.loadPriority()).add(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return List.copyOf(map.values());
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean loadedAll = false;
|
private static boolean loadedAll = false;
|
||||||
public static void loadAll() {
|
public static void loadAll() {
|
||||||
if (loadedAll) return;
|
if (loadedAll) return;
|
||||||
@ -86,48 +111,66 @@ public class ResourceLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void loadResources(boolean doReload) {
|
public static void loadResources(boolean doReload) {
|
||||||
for (Class<?> resourceDefinition : getResourceDefClasses()) {
|
long startTime = System.nanoTime();
|
||||||
ResourceType type = resourceDefinition.getAnnotation(ResourceType.class);
|
val errors = new ConcurrentLinkedQueue<Pair<String, Exception>>(); // Logger in a parallel stream will deadlock
|
||||||
|
|
||||||
if (type == null) {
|
getResourceDefClassesPrioritySets().forEach(classes -> {
|
||||||
continue;
|
classes.stream()
|
||||||
}
|
.parallel().unordered()
|
||||||
|
.forEach(c -> {
|
||||||
|
val type = c.getAnnotation(ResourceType.class);
|
||||||
|
if (type == null) return;
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
val map = GameData.getMapByResourceDef(c);
|
||||||
Int2ObjectMap map = GameData.getMapByResourceDef(resourceDefinition);
|
if (map == null) return;
|
||||||
|
|
||||||
if (map == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loadFromResource(resourceDefinition, type, map, doReload);
|
loadFromResource(c, type, map, doReload);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Grasscutter.getLogger().error("Error loading resource file: " + Arrays.toString(type.name()), e.getLocalizedMessage());
|
errors.add(Pair.of(Arrays.toString(type.name()), e));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
errors.forEach(pair -> Grasscutter.getLogger().error("Error loading resource file: " + pair.left(), pair.right()));
|
||||||
|
long endTime = System.nanoTime();
|
||||||
|
long ns = (endTime - startTime); //divide by 1000000 to get milliseconds.
|
||||||
|
Grasscutter.getLogger().debug("Loading resources took "+ns+"ns == "+ns/1000000+"ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
protected static void loadFromResource(Class<?> c, ResourceType type, Int2ObjectMap map, boolean doReload) throws Exception {
|
protected static void loadFromResource(Class<?> c, ResourceType type, Int2ObjectMap map, boolean doReload) throws Exception {
|
||||||
if (!loadedResources.contains(c.getSimpleName()) || doReload) {
|
val simpleName = c.getSimpleName();
|
||||||
|
if (doReload || !loadedResources.contains(simpleName)) {
|
||||||
for (String name : type.name()) {
|
for (String name : type.name()) {
|
||||||
loadFromResource(c, name, map);
|
loadFromResource(c, FileUtils.getExcelPath(name), map);
|
||||||
}
|
}
|
||||||
loadedResources.add(c.getSimpleName());
|
loadedResources.add(simpleName);
|
||||||
Grasscutter.getLogger().debug("Loaded " + map.size() + " " + c.getSimpleName() + "s.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
protected static <T> void loadFromResource(Class<T> c, String fileName, Int2ObjectMap map) throws Exception {
|
protected static <T> void loadFromResource(Class<T> c, Path filename, Int2ObjectMap map) throws Exception {
|
||||||
List<T> list = JsonUtils.loadToList(getResourcePath("ExcelBinOutput/" + fileName), c);
|
val results = switch (FileUtils.getFileExtension(filename)) {
|
||||||
|
case "json" -> JsonUtils.loadToList(filename, c);
|
||||||
for (T o : list) {
|
case "tsj" -> TsvUtils.loadTsjToListSetField(filename, c);
|
||||||
|
case "tsv" -> TsvUtils.loadTsvToListSetField(filename, c);
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
if (results == null) return;
|
||||||
|
results.forEach(o -> {
|
||||||
GameResource res = (GameResource) o;
|
GameResource res = (GameResource) o;
|
||||||
res.onLoad();
|
res.onLoad();
|
||||||
map.put(res.getId(), res);
|
map.put(res.getId(), res);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
protected static <T> void loadFromResource(Class<T> c, String fileName, Int2ObjectMap map) throws Exception {
|
||||||
|
JsonUtils.loadToList(getResourcePath("ExcelBinOutput/" + fileName), c).forEach(o -> {
|
||||||
|
GameResource res = (GameResource) o;
|
||||||
|
res.onLoad();
|
||||||
|
map.put(res.getId(), res);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ScenePointConfig { // Sadly this doesn't work as a local class in loadScenePoints()
|
public class ScenePointConfig { // Sadly this doesn't work as a local class in loadScenePoints()
|
||||||
|
@ -2,6 +2,8 @@ package emu.grasscutter.data;
|
|||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface ResourceType {
|
public @interface ResourceType {
|
||||||
@ -28,5 +30,9 @@ public @interface ResourceType {
|
|||||||
public int value() {
|
public int value() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<LoadPriority> getInOrder() {
|
||||||
|
return Stream.of(LoadPriority.values()).sorted((x, y) -> y.value() - x.value()).toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,18 +13,15 @@ import java.util.List;
|
|||||||
@Getter
|
@Getter
|
||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
public class ActivityWatcherData extends GameResource {
|
public class ActivityWatcherData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
int id;
|
int id;
|
||||||
int rewardID;
|
int rewardID;
|
||||||
int progress;
|
int progress;
|
||||||
WatcherTrigger triggerConfig;
|
WatcherTrigger triggerConfig;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
triggerConfig.paramList = triggerConfig.paramList.stream().filter(x -> !x.isBlank()).toList();
|
triggerConfig.paramList = triggerConfig.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList();
|
||||||
triggerConfig.watcherTriggerType = WatcherTriggerType.getTypeByName(triggerConfig.triggerType);
|
triggerConfig.watcherTriggerType = WatcherTriggerType.getTypeByName(triggerConfig.triggerType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ public class AvatarData extends GameResource {
|
|||||||
private float criticalHurt;
|
private float criticalHurt;
|
||||||
|
|
||||||
private List<PropGrowCurve> propGrowCurves;
|
private List<PropGrowCurve> propGrowCurves;
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
// Transient
|
// Transient
|
||||||
@ -60,11 +61,6 @@ public class AvatarData extends GameResource {
|
|||||||
@Getter private int nameCardRewardId;
|
@Getter private int nameCardRewardId;
|
||||||
@Getter private int nameCardId;
|
@Getter private int nameCardId;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBaseHp(int level) {
|
public float getBaseHp(int level) {
|
||||||
try {
|
try {
|
||||||
return this.hpBase * this.hpGrowthCurve[level - 1];
|
return this.hpBase * this.hpGrowthCurve[level - 1];
|
||||||
|
@ -7,26 +7,18 @@ import emu.grasscutter.game.props.ElementType;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "AvatarSkillExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
|
@ResourceType(name = "AvatarSkillExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
|
||||||
|
@Getter
|
||||||
public class AvatarSkillData extends GameResource {
|
public class AvatarSkillData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
@Getter private float cdTime;
|
private float cdTime;
|
||||||
@Getter private int costElemVal;
|
private int costElemVal;
|
||||||
@Getter private int maxChargeNum;
|
private int maxChargeNum;
|
||||||
@Getter private int triggerID;
|
private int triggerID;
|
||||||
@Getter private boolean isAttackCameraLock;
|
private boolean isAttackCameraLock;
|
||||||
@Getter private int proudSkillGroupId;
|
private int proudSkillGroupId;
|
||||||
@Getter private ElementType costElemType;
|
private ElementType costElemType;
|
||||||
@Getter private long nameTextMapHash;
|
private long nameTextMapHash;
|
||||||
@Getter private long descTextMapHash;
|
private long descTextMapHash;
|
||||||
@Getter private String abilityName;
|
private String abilityName;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,31 +18,27 @@ import it.unimi.dsi.fastutil.ints.IntList;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "AvatarSkillDepotExcelConfigData.json", loadPriority = LoadPriority.HIGH)
|
@ResourceType(name = "AvatarSkillDepotExcelConfigData.json", loadPriority = LoadPriority.HIGH)
|
||||||
|
@Getter
|
||||||
public class AvatarSkillDepotData extends GameResource {
|
public class AvatarSkillDepotData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
@Getter private int energySkill;
|
private int energySkill;
|
||||||
@Getter private int attackModeSkill;
|
private int attackModeSkill;
|
||||||
|
|
||||||
@Getter private List<Integer> skills;
|
private List<Integer> skills;
|
||||||
@Getter private List<Integer> subSkills;
|
private List<Integer> subSkills;
|
||||||
@Getter private List<String> extraAbilities;
|
private List<String> extraAbilities;
|
||||||
@Getter private List<Integer> talents;
|
private List<Integer> talents;
|
||||||
@Getter private List<InherentProudSkillOpens> inherentProudSkillOpens;
|
private List<InherentProudSkillOpens> inherentProudSkillOpens;
|
||||||
|
|
||||||
@Getter private String talentStarName;
|
private String talentStarName;
|
||||||
@Getter private String skillDepotAbilityGroup;
|
private String skillDepotAbilityGroup;
|
||||||
|
|
||||||
// Transient
|
// Transient
|
||||||
@Getter private AvatarSkillData energySkillData;
|
private AvatarSkillData energySkillData;
|
||||||
@Getter private ElementType elementType;
|
private ElementType elementType;
|
||||||
@Getter private IntList abilities;
|
private IntList abilities;
|
||||||
@Getter private int talentCostItemId;
|
private int talentCostItemId;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAbilities(AbilityEmbryoEntry info) {
|
public void setAbilities(AbilityEmbryoEntry info) {
|
||||||
this.abilities = new IntArrayList(info.getAbilities().length);
|
this.abilities = new IntArrayList(info.getAbilities().length);
|
||||||
@ -77,9 +73,10 @@ public class AvatarSkillDepotData extends GameResource {
|
|||||||
.ifPresent(itemId -> this.talentCostItemId = itemId);
|
.ifPresent(itemId -> this.talentCostItemId = itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
public static class InherentProudSkillOpens {
|
public static class InherentProudSkillOpens {
|
||||||
@Getter private int proudSkillGroupId;
|
private int proudSkillGroupId;
|
||||||
@Getter private int needAvatarPromoteLevel;
|
private int needAvatarPromoteLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntStream getSkillsAndEnergySkill() {
|
public IntStream getSkillsAndEnergySkill() {
|
||||||
|
@ -9,16 +9,14 @@ import emu.grasscutter.data.ResourceType;
|
|||||||
import emu.grasscutter.game.props.BattlePassMissionRefreshType;
|
import emu.grasscutter.game.props.BattlePassMissionRefreshType;
|
||||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||||
import emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.MissionStatus;
|
import emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.MissionStatus;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.experimental.FieldDefaults;
|
|
||||||
|
|
||||||
@ResourceType(name = {"BattlePassMissionExcelConfigData.json"})
|
@ResourceType(name = {"BattlePassMissionExcelConfigData.json"})
|
||||||
@Getter
|
@Getter
|
||||||
public class BattlePassMissionData extends GameResource {
|
public class BattlePassMissionData extends GameResource {
|
||||||
private int addPoint;
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
|
private int addPoint;
|
||||||
private int scheduleId;
|
private int scheduleId;
|
||||||
private int progress;
|
private int progress;
|
||||||
private TriggerConfig triggerConfig;
|
private TriggerConfig triggerConfig;
|
||||||
@ -26,11 +24,6 @@ public class BattlePassMissionData extends GameResource {
|
|||||||
|
|
||||||
private transient Set<Integer> mainParams;
|
private transient Set<Integer> mainParams;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WatcherTriggerType getTriggerType() {
|
public WatcherTriggerType getTriggerType() {
|
||||||
return this.getTriggerConfig().getTriggerType();
|
return this.getTriggerConfig().getTriggerType();
|
||||||
}
|
}
|
||||||
@ -47,8 +40,11 @@ public class BattlePassMissionData extends GameResource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
if (this.getTriggerConfig() != null && getTriggerConfig().getParamList()[0].length() > 0) {
|
if (this.getTriggerConfig() != null) {
|
||||||
this.mainParams = Arrays.stream(getTriggerConfig().getParamList()[0].split("[:;,]")).map(Integer::parseInt).collect(Collectors.toSet());
|
var params = getTriggerConfig().getParamList()[0];
|
||||||
|
if ((params != null) && !params.isEmpty()) {
|
||||||
|
this.mainParams = Arrays.stream(params.split("[:;,]")).map(Integer::parseInt).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,40 +7,39 @@ import emu.grasscutter.data.ResourceType;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "BlossomRefreshExcelConfigData.json")
|
@ResourceType(name = "BlossomRefreshExcelConfigData.json")
|
||||||
|
@Getter
|
||||||
public class BlossomRefreshExcelConfigData extends GameResource {
|
public class BlossomRefreshExcelConfigData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
// Map details
|
// Map details
|
||||||
@Getter private long nameTextMapHash;
|
private long nameTextMapHash;
|
||||||
@Getter private long descTextMapHash;
|
private long descTextMapHash;
|
||||||
@Getter private String icon;
|
private String icon;
|
||||||
@Getter private String clientShowType; // BLOSSOM_SHOWTYPE_CHALLENGE, BLOSSOM_SHOWTYPE_NPCTALK
|
private String clientShowType; // BLOSSOM_SHOWTYPE_CHALLENGE, BLOSSOM_SHOWTYPE_NPCTALK
|
||||||
|
|
||||||
// Refresh details
|
// Refresh details
|
||||||
@Getter private String refreshType; // Leyline blossoms, magical ore outcrops
|
private String refreshType; // Leyline blossoms, magical ore outcrops
|
||||||
@Getter private int refreshCount; // Number of entries to spawn at refresh (1 for each leyline type for each city, 4 for magical ore for each city)
|
private int refreshCount; // Number of entries to spawn at refresh (1 for each leyline type for each city, 4 for magical ore for each city)
|
||||||
@Getter private String refreshTime; // Server time-of-day to refresh at
|
private String refreshTime; // Server time-of-day to refresh at
|
||||||
@Getter private RefreshCond[] refreshCondVec; // AR requirements etc.
|
private RefreshCond[] refreshCondVec; // AR requirements etc.
|
||||||
|
|
||||||
@Getter private int cityId;
|
private int cityId;
|
||||||
@Getter private int blossomChestId; // 1 for mora, 2 for exp
|
private int blossomChestId; // 1 for mora, 2 for exp
|
||||||
@Getter private Drop[] dropVec;
|
private Drop[] dropVec;
|
||||||
|
|
||||||
// Unknown details
|
// Unknown details
|
||||||
// @Getter private int reviseLevel;
|
// @Getter private int reviseLevel;
|
||||||
// @Getter private int campUpdateNeedCount; // Always 1 if specified
|
// @Getter private int campUpdateNeedCount; // Always 1 if specified
|
||||||
|
|
||||||
@Override
|
@Getter
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Drop {
|
public static class Drop {
|
||||||
@Getter int dropId;
|
int dropId;
|
||||||
@Getter int previewReward;
|
int previewReward;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
public static class RefreshCond {
|
public static class RefreshCond {
|
||||||
@Getter String type;
|
String type;
|
||||||
@Getter List<Integer> param;
|
List<Integer> param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,27 +8,23 @@ import lombok.Setter;
|
|||||||
import lombok.experimental.FieldDefaults;
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ResourceType(name = "ChapterExcelConfigData.json")
|
@ResourceType(name = "ChapterExcelConfigData.json")
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter // TODO: remove on next API break
|
||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
public class ChapterData extends GameResource {
|
public class ChapterData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
int id;
|
int id;
|
||||||
int beginQuestId;
|
int beginQuestId;
|
||||||
int endQuestId;
|
int endQuestId;
|
||||||
int needPlayerLevel;
|
int needPlayerLevel;
|
||||||
|
|
||||||
|
// Why public? TODO: privatise next API break
|
||||||
public static final Map<Integer, ChapterData> beginQuestChapterMap = new HashMap<>();
|
public static final Map<Integer, ChapterData> beginQuestChapterMap = new HashMap<>();
|
||||||
public static final Map<Integer, ChapterData> endQuestChapterMap = new HashMap<>();
|
public static final Map<Integer, ChapterData> endQuestChapterMap = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
beginQuestChapterMap.put(beginQuestId, this);
|
beginQuestChapterMap.put(beginQuestId, this);
|
||||||
|
@ -22,9 +22,4 @@ public class CityData extends GameResource {
|
|||||||
public int getId() {
|
public int getId() {
|
||||||
return this.cityId;
|
return this.cityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
super.onLoad();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,15 @@ import emu.grasscutter.data.ResourceType;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = {"AnimalCodexExcelConfigData.json"})
|
@ResourceType(name = {"AnimalCodexExcelConfigData.json"})
|
||||||
|
@Getter
|
||||||
public class CodexAnimalData extends GameResource {
|
public class CodexAnimalData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int Id;
|
private int Id;
|
||||||
@Getter private String type;
|
private String type;
|
||||||
@Getter private int describeId;
|
private int describeId;
|
||||||
@Getter private int sortOrder;
|
private int sortOrder;
|
||||||
@SerializedName(value="countType", alternate={"OCCLHPBCDGL"})
|
@SerializedName(value="countType", alternate={"OCCLHPBCDGL"})
|
||||||
@Getter private CountType countType;
|
private CountType countType;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CountType {
|
public enum CountType {
|
||||||
CODEX_COUNT_TYPE_KILL,
|
CODEX_COUNT_TYPE_KILL,
|
||||||
|
@ -8,19 +8,15 @@ import lombok.Getter;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ResourceType(name = {"CompoundExcelConfigData.json"},loadPriority = ResourceType.LoadPriority.LOW)
|
@ResourceType(name = {"CompoundExcelConfigData.json"},loadPriority = ResourceType.LoadPriority.LOW)
|
||||||
|
@Getter
|
||||||
public class CompoundData extends GameResource {
|
public class CompoundData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
|
private int groupId;
|
||||||
@Override
|
private int rankLevel;
|
||||||
public int getId() {return this.id;}
|
private boolean isDefaultUnlocked;
|
||||||
@Getter private int groupId;
|
private int costTime;
|
||||||
@Getter private int rankLevel;
|
private int queueSize;
|
||||||
@Getter private boolean isDefaultUnlocked;
|
private List<ItemParamData> inputVec;
|
||||||
@Getter private int costTime;
|
private List<ItemParamData> outputVec;
|
||||||
@Getter private int queueSize;
|
|
||||||
@Getter private List<ItemParamData> inputVec;
|
|
||||||
@Getter private List<ItemParamData> outputVec;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad(){}
|
|
||||||
}
|
}
|
||||||
|
@ -9,21 +9,15 @@ import emu.grasscutter.data.common.ItemParamData;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = {"CookRecipeExcelConfigData.json"}, loadPriority = LoadPriority.LOW)
|
@ResourceType(name = {"CookRecipeExcelConfigData.json"}, loadPriority = LoadPriority.LOW)
|
||||||
|
@Getter
|
||||||
public class CookRecipeData extends GameResource {
|
public class CookRecipeData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
@Getter private int rankLevel;
|
private int rankLevel;
|
||||||
@Getter boolean isDefaultUnlocked;
|
private boolean isDefaultUnlocked;
|
||||||
@Getter int maxProficiency;
|
private int maxProficiency;
|
||||||
|
|
||||||
@Getter List<ItemParamData> qualityOutputVec;
|
private List<ItemParamData> qualityOutputVec;
|
||||||
@Getter List<ItemParamData> inputVec;
|
private List<ItemParamData> inputVec;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,11 @@ import emu.grasscutter.data.ResourceType;
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "DailyDungeonConfigData.json")
|
@ResourceType(name = "DailyDungeonConfigData.json")
|
||||||
public class DailyDungeonData extends GameResource {
|
public class DailyDungeonData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
private int[] monday;
|
private int[] monday;
|
||||||
private int[] tuesday;
|
private int[] tuesday;
|
||||||
@ -26,11 +28,6 @@ public class DailyDungeonData extends GameResource {
|
|||||||
this.map = new Int2ObjectOpenHashMap<>();
|
this.map = new Int2ObjectOpenHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getDungeonsByDay(int day) {
|
public int[] getDungeonsByDay(int day) {
|
||||||
return map.getOrDefault(day, empty);
|
return map.getOrDefault(day, empty);
|
||||||
}
|
}
|
||||||
|
@ -3,46 +3,23 @@ package emu.grasscutter.data.excels;
|
|||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import lombok.Getter;
|
||||||
import emu.grasscutter.game.props.SceneType;
|
|
||||||
|
|
||||||
@ResourceType(name = "DungeonExcelConfigData.json")
|
@ResourceType(name = "DungeonExcelConfigData.json")
|
||||||
public class DungeonData extends GameResource {
|
public class DungeonData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
private int sceneId;
|
@Getter private int sceneId;
|
||||||
private int showLevel;
|
@Getter private int showLevel;
|
||||||
private int passRewardPreviewID;
|
private int passRewardPreviewID;
|
||||||
private String involveType; // TODO enum
|
private String involveType; // TODO enum
|
||||||
|
|
||||||
private RewardPreviewData previewData;
|
private RewardPreviewData previewData;
|
||||||
|
|
||||||
private int statueCostID;
|
@Getter private int statueCostID;
|
||||||
private int statueCostCount;
|
@Getter private int statueCostCount;
|
||||||
|
|
||||||
@Override
|
public RewardPreviewData getRewardPreview() {return previewData;}
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSceneId() {
|
|
||||||
return sceneId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getShowLevel() {
|
|
||||||
return showLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RewardPreviewData getRewardPreview() {
|
|
||||||
return previewData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStatueCostID() {
|
|
||||||
return statueCostID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStatueCostCount() {
|
|
||||||
return statueCostCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
|
@ -7,19 +7,10 @@ import lombok.Setter;
|
|||||||
|
|
||||||
@ResourceType(name = "DungeonEntryExcelConfigData.json")
|
@ResourceType(name = "DungeonEntryExcelConfigData.json")
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter // TODO: remove this next API break
|
||||||
public class DungeonEntryData extends GameResource {
|
public class DungeonEntryData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
|
private int id;
|
||||||
private int dungeonEntryId;
|
private int dungeonEntryId;
|
||||||
private int sceneId;
|
private int sceneId;
|
||||||
private int id;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,12 @@ import emu.grasscutter.data.GameResource;
|
|||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = {"ForgeExcelConfigData.json"}, loadPriority = LoadPriority.HIGHEST)
|
@ResourceType(name = {"ForgeExcelConfigData.json"}, loadPriority = LoadPriority.HIGHEST)
|
||||||
|
@Getter
|
||||||
public class ForgeData extends GameResource {
|
public class ForgeData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
private int playerLevel;
|
private int playerLevel;
|
||||||
private int forgeType;
|
private int forgeType;
|
||||||
@ -21,57 +24,4 @@ public class ForgeData extends GameResource {
|
|||||||
private int priority;
|
private int priority;
|
||||||
private int forgePoint;
|
private int forgePoint;
|
||||||
private List<ItemParamData> materialItems;
|
private List<ItemParamData> materialItems;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPlayerLevel() {
|
|
||||||
return playerLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getForgeType() {
|
|
||||||
return forgeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getResultItemId() {
|
|
||||||
return resultItemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getResultItemCount() {
|
|
||||||
return resultItemCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getForgeTime() {
|
|
||||||
return forgeTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getQueueNum() {
|
|
||||||
return queueNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getScoinCost() {
|
|
||||||
return scoinCost;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPriority() {
|
|
||||||
return priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getForgePoint() {
|
|
||||||
return forgePoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ItemParamData> getMaterialItems() {
|
|
||||||
return materialItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getShowItemId() {
|
|
||||||
return showItemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,12 @@ package emu.grasscutter.data.excels;
|
|||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import emu.grasscutter.game.props.EntityType;
|
import emu.grasscutter.game.props.EntityType;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "GadgetExcelConfigData.json")
|
@ResourceType(name = "GadgetExcelConfigData.json")
|
||||||
|
@Getter
|
||||||
public class GadgetData extends GameResource {
|
public class GadgetData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
private EntityType type;
|
private EntityType type;
|
||||||
@ -15,42 +18,4 @@ public class GadgetData extends GameResource {
|
|||||||
private String itemJsonName;
|
private String itemJsonName;
|
||||||
private long nameTextMapHash;
|
private long nameTextMapHash;
|
||||||
private int campID;
|
private int campID;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getJsonName() {
|
|
||||||
return jsonName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInteractive() {
|
|
||||||
return isInteractive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getTags() {
|
|
||||||
return tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getItemJsonName() {
|
|
||||||
return itemJsonName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNameTextMapHash() {
|
|
||||||
return nameTextMapHash;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCampID() {
|
|
||||||
return campID;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,4 @@ public class HomeWorldLevelData extends GameResource {
|
|||||||
public int getId() {
|
public int getId() {
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
super.onLoad();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import emu.grasscutter.data.GameData;
|
|||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.experimental.FieldDefaults;
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
@ -14,6 +13,7 @@ import java.util.List;
|
|||||||
@Getter
|
@Getter
|
||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
public class InvestigationMonsterData extends GameResource {
|
public class InvestigationMonsterData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
int id;
|
int id;
|
||||||
int cityId;
|
int cityId;
|
||||||
List<Integer> monsterIdList;
|
List<Integer> monsterIdList;
|
||||||
@ -23,10 +23,6 @@ public class InvestigationMonsterData extends GameResource {
|
|||||||
String monsterCategory;
|
String monsterCategory;
|
||||||
|
|
||||||
CityData cityData;
|
CityData cityData;
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
|
@ -25,6 +25,7 @@ import lombok.Getter;
|
|||||||
@Getter
|
@Getter
|
||||||
public class ItemData extends GameResource {
|
public class ItemData extends GameResource {
|
||||||
// Main
|
// Main
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
private int stackLimit = 1;
|
private int stackLimit = 1;
|
||||||
private int maxUseCount;
|
private int maxUseCount;
|
||||||
@ -81,17 +82,12 @@ public class ItemData extends GameResource {
|
|||||||
private List<Integer> furnType;
|
private List<Integer> furnType;
|
||||||
private List<Integer> furnitureGadgetID;
|
private List<Integer> furnitureGadgetID;
|
||||||
|
|
||||||
@SerializedName(value="roomSceneId", alternate={"DANFGGLKLNO", "JFDLJGDFIGL", "OHIANNAEEAK"})
|
@SerializedName(value="roomSceneId", alternate={"BMEPAMCNABE", "DANFGGLKLNO", "JFDLJGDFIGL", "OHIANNAEEAK"})
|
||||||
private int roomSceneId;
|
private int roomSceneId;
|
||||||
|
|
||||||
// Custom
|
// Custom
|
||||||
private transient IntSet addPropLevelSet;
|
private transient IntSet addPropLevelSet;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WeaponProperty[] getWeaponProperties() {
|
public WeaponProperty[] getWeaponProperties() {
|
||||||
return this.weaponProp;
|
return this.weaponProp;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,25 @@
|
|||||||
package emu.grasscutter.data.excels;
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||||
import emu.grasscutter.data.common.PropGrowCurve;
|
import emu.grasscutter.data.common.PropGrowCurve;
|
||||||
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import emu.grasscutter.game.props.MonsterType;
|
import emu.grasscutter.game.props.MonsterType;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "MonsterExcelConfigData.json", loadPriority = LoadPriority.LOW)
|
@ResourceType(name = "MonsterExcelConfigData.json", loadPriority = LoadPriority.LOW)
|
||||||
|
@Getter
|
||||||
public class MonsterData extends GameResource {
|
public class MonsterData extends GameResource {
|
||||||
|
static public Set<FightProperty> definedFightProperties = Set.of(FightProperty.FIGHT_PROP_BASE_HP, FightProperty.FIGHT_PROP_BASE_ATTACK, FightProperty.FIGHT_PROP_BASE_DEFENSE, FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT, FightProperty.FIGHT_PROP_FIRE_SUB_HURT, FightProperty.FIGHT_PROP_ELEC_SUB_HURT, FightProperty.FIGHT_PROP_WATER_SUB_HURT, FightProperty.FIGHT_PROP_GRASS_SUB_HURT, FightProperty.FIGHT_PROP_WIND_SUB_HURT, FightProperty.FIGHT_PROP_ROCK_SUB_HURT, FightProperty.FIGHT_PROP_ICE_SUB_HURT);
|
||||||
|
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
private String monsterName;
|
private String monsterName;
|
||||||
@ -28,9 +37,14 @@ public class MonsterData extends GameResource {
|
|||||||
private int describeId;
|
private int describeId;
|
||||||
private int combatBGMLevel;
|
private int combatBGMLevel;
|
||||||
private int entityBudgetLevel;
|
private int entityBudgetLevel;
|
||||||
private float hpBase;
|
|
||||||
private float attackBase;
|
@SerializedName("hpBase")
|
||||||
private float defenseBase;
|
private float baseHp;
|
||||||
|
@SerializedName("attackBase")
|
||||||
|
private float baseAttack;
|
||||||
|
@SerializedName("defenseBase")
|
||||||
|
private float baseDefense;
|
||||||
|
|
||||||
private float fireSubHurt;
|
private float fireSubHurt;
|
||||||
private float elecSubHurt;
|
private float elecSubHurt;
|
||||||
private float grassSubHurt;
|
private float grassSubHurt;
|
||||||
@ -47,125 +61,21 @@ public class MonsterData extends GameResource {
|
|||||||
private int weaponId;
|
private int weaponId;
|
||||||
private MonsterDescribeData describeData;
|
private MonsterDescribeData describeData;
|
||||||
|
|
||||||
@Override
|
public float getFightProperty(FightProperty prop) {
|
||||||
public int getId() {
|
return switch (prop) {
|
||||||
return this.id;
|
case FIGHT_PROP_BASE_HP -> this.baseHp;
|
||||||
}
|
case FIGHT_PROP_BASE_ATTACK -> this.baseAttack;
|
||||||
|
case FIGHT_PROP_BASE_DEFENSE -> this.baseDefense;
|
||||||
public String getMonsterName() {
|
case FIGHT_PROP_PHYSICAL_SUB_HURT -> this.physicalSubHurt;
|
||||||
return monsterName;
|
case FIGHT_PROP_FIRE_SUB_HURT -> this.fireSubHurt;
|
||||||
}
|
case FIGHT_PROP_ELEC_SUB_HURT -> this.elecSubHurt;
|
||||||
|
case FIGHT_PROP_WATER_SUB_HURT -> this.waterSubHurt;
|
||||||
public MonsterType getType() {
|
case FIGHT_PROP_GRASS_SUB_HURT -> this.grassSubHurt;
|
||||||
return type;
|
case FIGHT_PROP_WIND_SUB_HURT -> this.windSubHurt;
|
||||||
}
|
case FIGHT_PROP_ROCK_SUB_HURT -> this.rockSubHurt;
|
||||||
|
case FIGHT_PROP_ICE_SUB_HURT -> this.iceSubHurt;
|
||||||
public String getServerScript() {
|
default -> 0f;
|
||||||
return serverScript;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
public List<Integer> getAffix() {
|
|
||||||
return affix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAi() {
|
|
||||||
return ai;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getEquips() {
|
|
||||||
return equips;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<HpDrops> getHpDrops() {
|
|
||||||
return hpDrops;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getKillDropId() {
|
|
||||||
return killDropId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getExcludeWeathers() {
|
|
||||||
return excludeWeathers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFeatureTagGroupID() {
|
|
||||||
return featureTagGroupID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMpPropID() {
|
|
||||||
return mpPropID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSkin() {
|
|
||||||
return skin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDescribeId() {
|
|
||||||
return describeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCombatBGMLevel() {
|
|
||||||
return combatBGMLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEntityBudgetLevel() {
|
|
||||||
return entityBudgetLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBaseHp() {
|
|
||||||
return hpBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBaseAttack() {
|
|
||||||
return attackBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBaseDefense() {
|
|
||||||
return defenseBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getElecSubHurt() {
|
|
||||||
return elecSubHurt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getGrassSubHurt() {
|
|
||||||
return grassSubHurt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getWaterSubHurt() {
|
|
||||||
return waterSubHurt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getWindSubHurt() {
|
|
||||||
return windSubHurt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getIceSubHurt() {
|
|
||||||
return iceSubHurt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getPhysicalSubHurt() {
|
|
||||||
return physicalSubHurt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PropGrowCurve> getPropGrowCurves() {
|
|
||||||
return propGrowCurves;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNameTextMapHash() {
|
|
||||||
return nameTextMapHash;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCampID() {
|
|
||||||
return campID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MonsterDescribeData getDescribeData() {
|
|
||||||
return describeData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWeaponId() {
|
|
||||||
return weaponId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -186,15 +96,9 @@ public class MonsterData extends GameResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
public class HpDrops {
|
public class HpDrops {
|
||||||
private int DropId;
|
private int DropId;
|
||||||
private int HpPercent;
|
private int HpPercent;
|
||||||
|
|
||||||
public int getDropId(){
|
|
||||||
return this.DropId;
|
|
||||||
}
|
|
||||||
public int getHpPercent(){
|
|
||||||
return this.HpPercent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,33 +3,14 @@ package emu.grasscutter.data.excels;
|
|||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "MonsterDescribeExcelConfigData.json", loadPriority = LoadPriority.HIGH)
|
@ResourceType(name = "MonsterDescribeExcelConfigData.json", loadPriority = LoadPriority.HIGH)
|
||||||
|
@Getter
|
||||||
public class MonsterDescribeData extends GameResource {
|
public class MonsterDescribeData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
private long nameTextMapHash;
|
private long nameTextMapHash;
|
||||||
private int titleID;
|
private int titleID;
|
||||||
private int specialNameLabID;
|
private int specialNameLabID;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNameTextMapHash() {
|
|
||||||
return nameTextMapHash;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTitleID() {
|
|
||||||
return titleID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSpecialNameLabID() {
|
|
||||||
return specialNameLabID;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,8 @@ import lombok.experimental.FieldDefaults;
|
|||||||
@Getter
|
@Getter
|
||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
public class MusicGameBasicData extends GameResource {
|
public class MusicGameBasicData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
int id;
|
int id;
|
||||||
int musicID;
|
int musicID;
|
||||||
int musicLevel;
|
int musicLevel;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,12 @@ package emu.grasscutter.data.excels;
|
|||||||
|
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "NpcExcelConfigData.json")
|
@ResourceType(name = "NpcExcelConfigData.json")
|
||||||
|
@Getter
|
||||||
public class NpcData extends GameResource {
|
public class NpcData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
private String jsonName;
|
private String jsonName;
|
||||||
@ -19,54 +22,4 @@ public class NpcData extends GameResource {
|
|||||||
|
|
||||||
private long nameTextMapHash;
|
private long nameTextMapHash;
|
||||||
private int campID;
|
private int campID;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getJsonName() {
|
|
||||||
return jsonName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAlias() {
|
|
||||||
return alias;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getScriptDataPath() {
|
|
||||||
return scriptDataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLuaDataPath() {
|
|
||||||
return luaDataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isIsInteractive() {
|
|
||||||
return isInteractive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHasMove() {
|
|
||||||
return hasMove;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDyePart() {
|
|
||||||
return dyePart;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBillboardIcon() {
|
|
||||||
return billboardIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNameTextMapHash() {
|
|
||||||
return nameTextMapHash;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCampID() {
|
|
||||||
return campID;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,14 @@ package emu.grasscutter.data.excels;
|
|||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@ResourceType(name = "OpenStateConfigData.json", loadPriority = ResourceType.LoadPriority.HIGHEST)
|
@ResourceType(name = "OpenStateConfigData.json", loadPriority = ResourceType.LoadPriority.HIGHEST)
|
||||||
public class OpenStateData extends GameResource {
|
public class OpenStateData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
@Getter private boolean defaultState;
|
@Getter private boolean defaultState;
|
||||||
@Getter private boolean allowClientOpen;
|
@Getter private boolean allowClientOpen;
|
||||||
@ -32,11 +31,6 @@ public class OpenStateData extends GameResource {
|
|||||||
OPEN_STATE_COND_PARENT_QUEST;
|
OPEN_STATE_COND_PARENT_QUEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
// Add this open state to the global list.
|
// Add this open state to the global list.
|
||||||
|
@ -11,18 +11,13 @@ import java.util.List;
|
|||||||
|
|
||||||
@ResourceType(name = "PersonalLineExcelConfigData.json")
|
@ResourceType(name = "PersonalLineExcelConfigData.json")
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter // TODO: remove setters next API break
|
||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
public class PersonalLineData extends GameResource {
|
public class PersonalLineData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
int id;
|
int id;
|
||||||
int avatarID;
|
int avatarID;
|
||||||
List<Integer> preQuestId;
|
List<Integer> preQuestId;
|
||||||
int startQuestId;
|
int startQuestId;
|
||||||
int chapterId;
|
int chapterId;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,46 +1,23 @@
|
|||||||
package emu.grasscutter.data.excels;
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
|
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.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "ReliquaryAffixExcelConfigData.json")
|
@ResourceType(name = "ReliquaryAffixExcelConfigData.json")
|
||||||
|
@Getter
|
||||||
public class ReliquaryAffixData extends GameResource {
|
public class ReliquaryAffixData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
private int depotId;
|
private int depotId;
|
||||||
private int groupId;
|
private int groupId;
|
||||||
private FightProperty propType;
|
@SerializedName("propType")
|
||||||
|
private FightProperty fightProp;
|
||||||
private float propValue;
|
private float propValue;
|
||||||
private int weight;
|
private int weight;
|
||||||
private int upgradeWeight;
|
private int upgradeWeight;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDepotId() {
|
|
||||||
return depotId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGroupId() {
|
|
||||||
return groupId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getPropValue() {
|
|
||||||
return propValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWeight() {
|
|
||||||
return weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUpgradeWeight() {
|
|
||||||
return upgradeWeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FightProperty getFightProp() {
|
|
||||||
return propType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,36 +7,19 @@ import emu.grasscutter.data.ResourceType;
|
|||||||
import emu.grasscutter.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import lombok.Getter;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
||||||
|
|
||||||
@ResourceType(name = "ReliquaryLevelExcelConfigData.json")
|
@ResourceType(name = "ReliquaryLevelExcelConfigData.json")
|
||||||
public class ReliquaryLevelData extends GameResource {
|
public class ReliquaryLevelData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
private Int2FloatMap propMap;
|
private Int2FloatMap propMap;
|
||||||
|
|
||||||
private int rank;
|
@Getter private int rank;
|
||||||
private int level;
|
@Getter private int level;
|
||||||
private int exp;
|
@Getter private int exp;
|
||||||
private List<RelicLevelProperty> addProps;
|
private List<RelicLevelProperty> addProps;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRank() {
|
|
||||||
return rank;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLevel() {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getExp() {
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getPropValue(FightProperty prop) {
|
public float getPropValue(FightProperty prop) {
|
||||||
return getPropValue(prop.getId());
|
return getPropValue(prop.getId());
|
||||||
}
|
}
|
||||||
@ -54,16 +37,9 @@ public class ReliquaryLevelData extends GameResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
public class RelicLevelProperty {
|
public class RelicLevelProperty {
|
||||||
private String propType;
|
private String propType;
|
||||||
private float value;
|
private float value;
|
||||||
|
|
||||||
public String getPropType() {
|
|
||||||
return propType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,20 @@
|
|||||||
package emu.grasscutter.data.excels;
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
|
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.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "ReliquaryMainPropExcelConfigData.json")
|
@ResourceType(name = "ReliquaryMainPropExcelConfigData.json")
|
||||||
|
@Getter
|
||||||
public class ReliquaryMainPropData extends GameResource {
|
public class ReliquaryMainPropData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
private int propDepotId;
|
private int propDepotId;
|
||||||
private FightProperty propType;
|
@SerializedName("propType")
|
||||||
|
private FightProperty fightProp;
|
||||||
private int weight;
|
private int weight;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPropDepotId() {
|
|
||||||
return propDepotId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWeight() {
|
|
||||||
return weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FightProperty getFightProp() {
|
|
||||||
return propType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,22 @@
|
|||||||
package emu.grasscutter.data.excels;
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
|
||||||
import emu.grasscutter.data.GameData;
|
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
|
||||||
import emu.grasscutter.game.props.SceneType;
|
import lombok.Getter;
|
||||||
|
|
||||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
import emu.grasscutter.data.common.ItemParamStringData;
|
import emu.grasscutter.data.common.ItemParamStringData;
|
||||||
|
|
||||||
@ResourceType(name = "RewardPreviewExcelConfigData.json", loadPriority = LoadPriority.HIGH)
|
@ResourceType(name = "RewardPreviewExcelConfigData.json", loadPriority = LoadPriority.HIGH)
|
||||||
public class RewardPreviewData extends GameResource {
|
public class RewardPreviewData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
private ItemParamStringData[] previewItems;
|
private ItemParamStringData[] previewItems;
|
||||||
private ItemParamData[] previewItemsArray;
|
private ItemParamData[] previewItemsArray;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemParamData[] getPreviewItems() {
|
public ItemParamData[] getPreviewItems() {
|
||||||
return previewItemsArray;
|
return previewItemsArray;
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,19 @@
|
|||||||
package emu.grasscutter.data.excels;
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
import emu.grasscutter.data.GameData;
|
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.game.props.SceneType;
|
import emu.grasscutter.game.props.SceneType;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "SceneExcelConfigData.json")
|
@ResourceType(name = "SceneExcelConfigData.json")
|
||||||
|
@Getter
|
||||||
public class SceneData extends GameResource {
|
public class SceneData extends GameResource {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private int id;
|
private int id;
|
||||||
private SceneType type;
|
@SerializedName("type")
|
||||||
|
private SceneType sceneType;
|
||||||
private String scriptData;
|
private String scriptData;
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SceneType getSceneType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getScriptData() {
|
|
||||||
return scriptData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,11 @@ package emu.grasscutter.data.excels;
|
|||||||
|
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "TowerFloorExcelConfigData.json")
|
@ResourceType(name = "TowerFloorExcelConfigData.json")
|
||||||
|
@Getter
|
||||||
public class TowerFloorData extends GameResource {
|
public class TowerFloorData extends GameResource {
|
||||||
|
|
||||||
private int floorId;
|
private int floorId;
|
||||||
private int floorIndex;
|
private int floorIndex;
|
||||||
private int levelGroupId;
|
private int levelGroupId;
|
||||||
@ -17,33 +18,4 @@ public class TowerFloorData extends GameResource {
|
|||||||
public int getId() {
|
public int getId() {
|
||||||
return this.floorId;
|
return this.floorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
super.onLoad();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFloorId() {
|
|
||||||
return floorId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFloorIndex() {
|
|
||||||
return floorIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLevelGroupId() {
|
|
||||||
return levelGroupId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOverrideMonsterLevel() {
|
|
||||||
return overrideMonsterLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTeamNum() {
|
|
||||||
return teamNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFloorLevelConfigId() {
|
|
||||||
return floorLevelConfigId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package emu.grasscutter.database;
|
package emu.grasscutter.database;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.mongodb.client.result.DeleteResult;
|
import com.mongodb.client.result.DeleteResult;
|
||||||
|
|
||||||
@ -154,6 +155,11 @@ public final class DatabaseHelper {
|
|||||||
DatabaseManager.getAccountDatastore().find(Account.class).filter(Filters.eq("id", target.getId())).delete();
|
DatabaseManager.getAccountDatastore().find(Account.class).filter(Filters.eq("id", target.getId())).delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> Stream<T> getByGameClass(Class<T> classType) {
|
||||||
|
return DatabaseManager.getGameDatastore().find(classType).stream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public static List<Player> getAllPlayers() {
|
public static List<Player> getAllPlayers() {
|
||||||
return DatabaseManager.getGameDatastore().find(Player.class).stream().toList();
|
return DatabaseManager.getGameDatastore().find(Player.class).stream().toList();
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass.ShowAvatarInfo;
|
|||||||
import emu.grasscutter.net.proto.ShowEquipOuterClass.ShowEquip;
|
import emu.grasscutter.net.proto.ShowEquipOuterClass.ShowEquip;
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
import emu.grasscutter.utils.ProtoHelper;
|
import emu.grasscutter.utils.ProtoHelper;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
@ -89,7 +90,7 @@ public class Avatar {
|
|||||||
private float currentEnergy;
|
private float currentEnergy;
|
||||||
|
|
||||||
@Transient @Getter private final Int2ObjectMap<GameItem> equips;
|
@Transient @Getter private final Int2ObjectMap<GameItem> equips;
|
||||||
@Transient private final Int2FloatOpenHashMap fightProp;
|
@Transient @Getter private final Int2FloatOpenHashMap fightProperties;
|
||||||
@Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides;
|
@Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides;
|
||||||
@Transient @Getter private Set<String> extraAbilityEmbryos;
|
@Transient @Getter private Set<String> extraAbilityEmbryos;
|
||||||
|
|
||||||
@ -115,7 +116,7 @@ public class Avatar {
|
|||||||
@Deprecated // Do not use. Morhpia only!
|
@Deprecated // Do not use. Morhpia only!
|
||||||
public Avatar() {
|
public Avatar() {
|
||||||
this.equips = new Int2ObjectOpenHashMap<>();
|
this.equips = new Int2ObjectOpenHashMap<>();
|
||||||
this.fightProp = new Int2FloatOpenHashMap();
|
this.fightProperties = new Int2FloatOpenHashMap();
|
||||||
this.fightPropOverrides = new Int2FloatOpenHashMap();
|
this.fightPropOverrides = new Int2FloatOpenHashMap();
|
||||||
this.extraAbilityEmbryos = new HashSet<>();
|
this.extraAbilityEmbryos = new HashSet<>();
|
||||||
this.fetters = new ArrayList<>(); // TODO Move to avatar
|
this.fetters = new ArrayList<>(); // TODO Move to avatar
|
||||||
@ -276,10 +277,6 @@ public class Avatar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
|
||||||
return fightProp;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
@ -399,9 +396,9 @@ public class Avatar {
|
|||||||
|
|
||||||
public void recalcStats(boolean forceSendAbilityChange) {
|
public void recalcStats(boolean forceSendAbilityChange) {
|
||||||
// Setup
|
// Setup
|
||||||
AvatarData data = this.getAvatarData();
|
var data = this.getAvatarData();
|
||||||
AvatarPromoteData promoteData = GameData.getAvatarPromoteData(data.getAvatarPromoteId(), this.getPromoteLevel());
|
var promoteData = GameData.getAvatarPromoteData(data.getAvatarPromoteId(), this.getPromoteLevel());
|
||||||
Int2IntOpenHashMap setMap = new Int2IntOpenHashMap();
|
var setMap = new Int2IntOpenHashMap();
|
||||||
|
|
||||||
// Extra ability embryos
|
// Extra ability embryos
|
||||||
Set<String> prevExtraAbilityEmbryos = this.getExtraAbilityEmbryos();
|
Set<String> prevExtraAbilityEmbryos = this.getExtraAbilityEmbryos();
|
||||||
@ -579,21 +576,11 @@ public class Avatar {
|
|||||||
// Add any skill strings from this constellation
|
// Add any skill strings from this constellation
|
||||||
|
|
||||||
// Set % stats
|
// Set % stats
|
||||||
this.setFightProperty(
|
FightProperty.forEachCompoundProperty(c -> this.setFightProperty(c.getResult(),
|
||||||
FightProperty.FIGHT_PROP_MAX_HP,
|
this.getFightProperty(c.getFlat()) + (this.getFightProperty(c.getBase()) * (1f + this.getFightProperty(c.getPercent())))));
|
||||||
(getFightProperty(FightProperty.FIGHT_PROP_BASE_HP) * (1f + getFightProperty(FightProperty.FIGHT_PROP_HP_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_HP)
|
|
||||||
);
|
|
||||||
this.setFightProperty(
|
|
||||||
FightProperty.FIGHT_PROP_CUR_ATTACK,
|
|
||||||
(getFightProperty(FightProperty.FIGHT_PROP_BASE_ATTACK) * (1f + getFightProperty(FightProperty.FIGHT_PROP_ATTACK_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_ATTACK)
|
|
||||||
);
|
|
||||||
this.setFightProperty(
|
|
||||||
FightProperty.FIGHT_PROP_CUR_DEFENSE,
|
|
||||||
(getFightProperty(FightProperty.FIGHT_PROP_BASE_DEFENSE) * (1f + getFightProperty(FightProperty.FIGHT_PROP_DEFENSE_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_DEFENSE)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Reapply all overrides
|
// Reapply all overrides
|
||||||
this.fightProp.putAll(this.fightPropOverrides);
|
this.fightProperties.putAll(this.fightPropOverrides);
|
||||||
|
|
||||||
// Set current hp
|
// Set current hp
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * hpPercent);
|
this.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * hpPercent);
|
||||||
|
@ -1,124 +0,0 @@
|
|||||||
package emu.grasscutter.game.avatar;
|
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
||||||
|
|
||||||
public enum AvatarStat {
|
|
||||||
FIGHT_PROP_NONE(0),
|
|
||||||
FIGHT_PROP_BASE_HP(1),
|
|
||||||
FIGHT_PROP_HP(2),
|
|
||||||
FIGHT_PROP_HP_PERCENT(3),
|
|
||||||
FIGHT_PROP_BASE_ATTACK(4),
|
|
||||||
FIGHT_PROP_ATTACK(5),
|
|
||||||
FIGHT_PROP_ATTACK_PERCENT(6),
|
|
||||||
FIGHT_PROP_BASE_DEFENSE(7),
|
|
||||||
FIGHT_PROP_DEFENSE(8),
|
|
||||||
FIGHT_PROP_DEFENSE_PERCENT(9),
|
|
||||||
FIGHT_PROP_BASE_SPEED(10),
|
|
||||||
FIGHT_PROP_SPEED_PERCENT(11),
|
|
||||||
FIGHT_PROP_HP_MP_PERCENT(12),
|
|
||||||
FIGHT_PROP_ATTACK_MP_PERCENT(13),
|
|
||||||
FIGHT_PROP_CRITICAL(20),
|
|
||||||
FIGHT_PROP_ANTI_CRITICAL(21),
|
|
||||||
FIGHT_PROP_CRITICAL_HURT(22),
|
|
||||||
FIGHT_PROP_CHARGE_EFFICIENCY(23),
|
|
||||||
FIGHT_PROP_ADD_HURT(24),
|
|
||||||
FIGHT_PROP_SUB_HURT(25),
|
|
||||||
FIGHT_PROP_HEAL_ADD(26),
|
|
||||||
FIGHT_PROP_HEALED_ADD(27),
|
|
||||||
FIGHT_PROP_ELEMENT_MASTERY(28),
|
|
||||||
FIGHT_PROP_PHYSICAL_SUB_HURT(29),
|
|
||||||
FIGHT_PROP_PHYSICAL_ADD_HURT(30),
|
|
||||||
FIGHT_PROP_DEFENCE_IGNORE_RATIO(31),
|
|
||||||
FIGHT_PROP_DEFENCE_IGNORE_DELTA(32),
|
|
||||||
FIGHT_PROP_FIRE_ADD_HURT(40),
|
|
||||||
FIGHT_PROP_ELEC_ADD_HURT(41),
|
|
||||||
FIGHT_PROP_WATER_ADD_HURT(42),
|
|
||||||
FIGHT_PROP_GRASS_ADD_HURT(43),
|
|
||||||
FIGHT_PROP_WIND_ADD_HURT(44),
|
|
||||||
FIGHT_PROP_ROCK_ADD_HURT(45),
|
|
||||||
FIGHT_PROP_ICE_ADD_HURT(46),
|
|
||||||
FIGHT_PROP_HIT_HEAD_ADD_HURT(47),
|
|
||||||
FIGHT_PROP_FIRE_SUB_HURT(50),
|
|
||||||
FIGHT_PROP_ELEC_SUB_HURT(51),
|
|
||||||
FIGHT_PROP_WATER_SUB_HURT(52),
|
|
||||||
FIGHT_PROP_GRASS_SUB_HURT(53),
|
|
||||||
FIGHT_PROP_WIND_SUB_HURT(54),
|
|
||||||
FIGHT_PROP_ROCK_SUB_HURT(55),
|
|
||||||
FIGHT_PROP_ICE_SUB_HURT(56),
|
|
||||||
FIGHT_PROP_EFFECT_HIT(60),
|
|
||||||
FIGHT_PROP_EFFECT_RESIST(61),
|
|
||||||
FIGHT_PROP_FREEZE_RESIST(62),
|
|
||||||
FIGHT_PROP_TORPOR_RESIST(63),
|
|
||||||
FIGHT_PROP_DIZZY_RESIST(64),
|
|
||||||
FIGHT_PROP_FREEZE_SHORTEN(65),
|
|
||||||
FIGHT_PROP_TORPOR_SHORTEN(66),
|
|
||||||
FIGHT_PROP_DIZZY_SHORTEN(67),
|
|
||||||
FIGHT_PROP_MAX_FIRE_ENERGY(70),
|
|
||||||
FIGHT_PROP_MAX_ELEC_ENERGY(71),
|
|
||||||
FIGHT_PROP_MAX_WATER_ENERGY(72),
|
|
||||||
FIGHT_PROP_MAX_GRASS_ENERGY(73),
|
|
||||||
FIGHT_PROP_MAX_WIND_ENERGY(74),
|
|
||||||
FIGHT_PROP_MAX_ICE_ENERGY(75),
|
|
||||||
FIGHT_PROP_MAX_ROCK_ENERGY(76),
|
|
||||||
FIGHT_PROP_SKILL_CD_MINUS_RATIO(80),
|
|
||||||
FIGHT_PROP_SHIELD_COST_MINUS_RATIO(81),
|
|
||||||
FIGHT_PROP_CUR_FIRE_ENERGY(1000),
|
|
||||||
FIGHT_PROP_CUR_ELEC_ENERGY(1001),
|
|
||||||
FIGHT_PROP_CUR_WATER_ENERGY(1002),
|
|
||||||
FIGHT_PROP_CUR_GRASS_ENERGY(1003),
|
|
||||||
FIGHT_PROP_CUR_WIND_ENERGY(1004),
|
|
||||||
FIGHT_PROP_CUR_ICE_ENERGY(1005),
|
|
||||||
FIGHT_PROP_CUR_ROCK_ENERGY(1006),
|
|
||||||
FIGHT_PROP_CUR_HP(1010),
|
|
||||||
FIGHT_PROP_MAX_HP(2000),
|
|
||||||
FIGHT_PROP_CUR_ATTACK(2001),
|
|
||||||
FIGHT_PROP_CUR_DEFENSE(2002),
|
|
||||||
FIGHT_PROP_CUR_SPEED(2003),
|
|
||||||
FIGHT_PROP_NONEXTRA_ATTACK(3000),
|
|
||||||
FIGHT_PROP_NONEXTRA_DEFENSE(3001),
|
|
||||||
FIGHT_PROP_NONEXTRA_CRITICAL(3002),
|
|
||||||
FIGHT_PROP_NONEXTRA_ANTI_CRITICAL(3003),
|
|
||||||
FIGHT_PROP_NONEXTRA_CRITICAL_HURT(3004),
|
|
||||||
FIGHT_PROP_NONEXTRA_CHARGE_EFFICIENCY(3005),
|
|
||||||
FIGHT_PROP_NONEXTRA_ELEMENT_MASTERY(3006),
|
|
||||||
FIGHT_PROP_NONEXTRA_PHYSICAL_SUB_HURT(3007),
|
|
||||||
FIGHT_PROP_NONEXTRA_FIRE_ADD_HURT(3008),
|
|
||||||
FIGHT_PROP_NONEXTRA_ELEC_ADD_HURT(3009),
|
|
||||||
FIGHT_PROP_NONEXTRA_WATER_ADD_HURT(3010),
|
|
||||||
FIGHT_PROP_NONEXTRA_GRASS_ADD_HURT(3011),
|
|
||||||
FIGHT_PROP_NONEXTRA_WIND_ADD_HURT(3012),
|
|
||||||
FIGHT_PROP_NONEXTRA_ROCK_ADD_HURT(3013),
|
|
||||||
FIGHT_PROP_NONEXTRA_ICE_ADD_HURT(3014),
|
|
||||||
FIGHT_PROP_NONEXTRA_FIRE_SUB_HURT(3015),
|
|
||||||
FIGHT_PROP_NONEXTRA_ELEC_SUB_HURT(3016),
|
|
||||||
FIGHT_PROP_NONEXTRA_WATER_SUB_HURT(3017),
|
|
||||||
FIGHT_PROP_NONEXTRA_GRASS_SUB_HURT(3018),
|
|
||||||
FIGHT_PROP_NONEXTRA_WIND_SUB_HURT(3019),
|
|
||||||
FIGHT_PROP_NONEXTRA_ROCK_SUB_HURT(3020),
|
|
||||||
FIGHT_PROP_NONEXTRA_ICE_SUB_HURT(3021),
|
|
||||||
FIGHT_PROP_NONEXTRA_SKILL_CD_MINUS_RATIO(3022),
|
|
||||||
FIGHT_PROP_NONEXTRA_SHIELD_COST_MINUS_RATIO(3023),
|
|
||||||
FIGHT_PROP_NONEXTRA_PHYSICAL_ADD_HURT(3024);
|
|
||||||
|
|
||||||
private final int id;
|
|
||||||
private static final Int2ObjectMap<AvatarStat> map = new Int2ObjectOpenHashMap<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
Stream.of(values()).forEach(e -> map.put(e.getId(), e));
|
|
||||||
}
|
|
||||||
|
|
||||||
private AvatarStat(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AvatarStat getStatById(int value) {
|
|
||||||
return map.getOrDefault(value, FIGHT_PROP_NONE);
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,7 +21,6 @@ import emu.grasscutter.net.proto.ChangeHpReasonOuterClass.ChangeHpReason;
|
|||||||
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
||||||
import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData;
|
import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData;
|
||||||
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
||||||
import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair;
|
|
||||||
import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType;
|
import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType;
|
||||||
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
|
import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason;
|
||||||
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
||||||
@ -38,19 +37,24 @@ import emu.grasscutter.utils.Position;
|
|||||||
import emu.grasscutter.utils.ProtoHelper;
|
import emu.grasscutter.utils.ProtoHelper;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
import lombok.Getter;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
|
||||||
public class EntityAvatar extends GameEntity {
|
public class EntityAvatar extends GameEntity {
|
||||||
private final Avatar avatar;
|
@Getter private final Avatar avatar;
|
||||||
|
|
||||||
private PlayerDieType killedType;
|
@Getter private PlayerDieType killedType;
|
||||||
private int killedBy;
|
@Getter private int killedBy;
|
||||||
|
|
||||||
|
public EntityAvatar(Avatar avatar) {
|
||||||
|
this(null, avatar);
|
||||||
|
}
|
||||||
|
|
||||||
public EntityAvatar(Scene scene, Avatar avatar) {
|
public EntityAvatar(Scene scene, Avatar avatar) {
|
||||||
super(scene);
|
super(scene);
|
||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
this.avatar.setCurrentEnergy();
|
this.avatar.setCurrentEnergy();
|
||||||
|
if (scene != null)
|
||||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.AVATAR);
|
this.id = getScene().getWorld().getNextEntityId(EntityIdType.AVATAR);
|
||||||
|
|
||||||
GameItem weapon = this.getAvatar().getWeapon();
|
GameItem weapon = this.getAvatar().getWeapon();
|
||||||
@ -59,47 +63,20 @@ public class EntityAvatar extends GameEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityAvatar(Avatar avatar) {
|
public Player getPlayer() {return this.avatar.getPlayer();}
|
||||||
super(null);
|
|
||||||
this.avatar = avatar;
|
|
||||||
this.avatar.setCurrentEnergy();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player getPlayer() {
|
|
||||||
return avatar.getPlayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Position getPosition() {
|
public Position getPosition() {return getPlayer().getPosition();}
|
||||||
return getPlayer().getPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Position getRotation() {
|
public Position getRotation() {return getPlayer().getRotation();}
|
||||||
return getPlayer().getRotation();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Avatar getAvatar() {
|
|
||||||
return avatar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getKilledBy() {
|
|
||||||
return killedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerDieType getKilledType() {
|
|
||||||
return killedType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAlive() {
|
public boolean isAlive() {
|
||||||
return this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) > 0f;
|
return this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) > 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public Int2FloatMap getFightProperties() {return getAvatar().getFightProperties();}
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
|
||||||
return getAvatar().getFightProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWeaponEntityId() {
|
public int getWeaponEntityId() {
|
||||||
if (getAvatar().getWeapon() != null) {
|
if (getAvatar().getWeapon() != null) {
|
||||||
@ -145,11 +122,8 @@ public class EntityAvatar extends GameEntity {
|
|||||||
|
|
||||||
public void clearEnergy(ChangeEnergyReason reason) {
|
public void clearEnergy(ChangeEnergyReason reason) {
|
||||||
// Fight props.
|
// Fight props.
|
||||||
FightProperty curEnergyProp = this.getAvatar().getSkillDepot().getElementType().getCurEnergyProp();
|
val curEnergyProp = this.getAvatar().getSkillDepot().getElementType().getCurEnergyProp();
|
||||||
FightProperty maxEnergyProp = this.getAvatar().getSkillDepot().getElementType().getMaxEnergyProp();
|
float curEnergy = this.getFightProperty(curEnergyProp);
|
||||||
|
|
||||||
// Get max energy.
|
|
||||||
float maxEnergy = this.avatar.getFightProperty(maxEnergyProp);
|
|
||||||
|
|
||||||
// Set energy to zero.
|
// Set energy to zero.
|
||||||
this.avatar.setCurrentEnergy(curEnergyProp, 0);
|
this.avatar.setCurrentEnergy(curEnergyProp, 0);
|
||||||
@ -158,7 +132,7 @@ public class EntityAvatar extends GameEntity {
|
|||||||
this.getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, curEnergyProp));
|
this.getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, curEnergyProp));
|
||||||
|
|
||||||
if (reason == ChangeEnergyReason.CHANGE_ENERGY_REASON_SKILL_START) {
|
if (reason == ChangeEnergyReason.CHANGE_ENERGY_REASON_SKILL_START) {
|
||||||
this.getScene().broadcastPacket(new PacketEntityFightPropChangeReasonNotify(this, curEnergyProp, -maxEnergy, reason));
|
this.getScene().broadcastPacket(new PacketEntityFightPropChangeReasonNotify(this, curEnergyProp, -curEnergy, reason));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,18 +141,16 @@ public class EntityAvatar extends GameEntity {
|
|||||||
}
|
}
|
||||||
public void addEnergy(float amount, PropChangeReason reason, boolean isFlat) {
|
public void addEnergy(float amount, PropChangeReason reason, boolean isFlat) {
|
||||||
// Get current and maximum energy for this avatar.
|
// Get current and maximum energy for this avatar.
|
||||||
FightProperty curEnergyProp = this.getAvatar().getSkillDepot().getElementType().getCurEnergyProp();
|
val elementType = this.getAvatar().getSkillDepot().getElementType();
|
||||||
FightProperty maxEnergyProp = this.getAvatar().getSkillDepot().getElementType().getMaxEnergyProp();
|
val curEnergyProp = elementType.getCurEnergyProp();
|
||||||
|
val maxEnergyProp = elementType.getMaxEnergyProp();
|
||||||
|
|
||||||
float curEnergy = this.getFightProperty(curEnergyProp);
|
float curEnergy = this.getFightProperty(curEnergyProp);
|
||||||
float maxEnergy = this.getFightProperty(maxEnergyProp);
|
float maxEnergy = this.getFightProperty(maxEnergyProp);
|
||||||
|
|
||||||
// Get energy recharge.
|
|
||||||
float energyRecharge = this.getFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY);
|
|
||||||
|
|
||||||
// Scale amount by energy recharge, if the amount is not flat.
|
// Scale amount by energy recharge, if the amount is not flat.
|
||||||
if (!isFlat) {
|
if (!isFlat) {
|
||||||
amount *= energyRecharge;
|
amount *= this.getFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the new energy value.
|
// Determine the new energy value.
|
||||||
|
@ -3,11 +3,23 @@ package emu.grasscutter.game.entity;
|
|||||||
import emu.grasscutter.data.binout.ConfigGadget;
|
import emu.grasscutter.data.binout.ConfigGadget;
|
||||||
import emu.grasscutter.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
|
import emu.grasscutter.utils.Position;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
public abstract class EntityBaseGadget extends GameEntity {
|
public abstract class EntityBaseGadget extends GameEntity {
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
|
protected final Position position;
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
|
protected final Position rotation;
|
||||||
|
|
||||||
public EntityBaseGadget(Scene scene) {
|
public EntityBaseGadget(Scene scene) {
|
||||||
|
this(scene, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityBaseGadget(Scene scene, Position position, Position rotation) {
|
||||||
super(scene);
|
super(scene);
|
||||||
|
this.position = position != null ? position.clone() : new Position();
|
||||||
|
this.rotation = rotation != null ? rotation.clone() : new Position();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract int getGadgetId();
|
public abstract int getGadgetId();
|
||||||
|
@ -19,30 +19,28 @@ import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
|||||||
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
||||||
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.Int2FloatMap;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
public class EntityClientGadget extends EntityBaseGadget {
|
public class EntityClientGadget extends EntityBaseGadget {
|
||||||
private final Player owner;
|
@Getter private final Player owner;
|
||||||
|
|
||||||
private final Position pos;
|
@Getter(onMethod = @__(@Override))
|
||||||
private final Position rot;
|
private int gadgetId;
|
||||||
|
|
||||||
private int configId;
|
@Getter private int campId;
|
||||||
private int campId;
|
@Getter private int campType;
|
||||||
private int campType;
|
@Getter private int ownerEntityId;
|
||||||
private int ownerEntityId;
|
@Getter private int targetEntityId;
|
||||||
private int targetEntityId;
|
@Getter private boolean asyncLoad;
|
||||||
private boolean asyncLoad;
|
|
||||||
|
|
||||||
private int originalOwnerEntityId;
|
@Getter private int originalOwnerEntityId;
|
||||||
|
|
||||||
public EntityClientGadget(Scene scene, Player player, EvtCreateGadgetNotify notify) {
|
public EntityClientGadget(Scene scene, Player player, EvtCreateGadgetNotify notify) {
|
||||||
super(scene);
|
super(scene, new Position(notify.getInitPos()), new Position(notify.getInitEulerAngles()));
|
||||||
this.owner = player;
|
this.owner = player;
|
||||||
this.id = notify.getEntityId();
|
this.id = notify.getEntityId();
|
||||||
this.pos = new Position(notify.getInitPos());
|
this.gadgetId = notify.getConfigId();
|
||||||
this.rot = new Position(notify.getInitEulerAngles());
|
|
||||||
this.configId = notify.getConfigId();
|
|
||||||
this.campId = notify.getCampId();
|
this.campId = notify.getCampId();
|
||||||
this.campType = notify.getCampType();
|
this.campType = notify.getCampType();
|
||||||
this.ownerEntityId = notify.getPropOwnerEntityId();
|
this.ownerEntityId = notify.getPropOwnerEntityId();
|
||||||
@ -58,61 +56,12 @@ public class EntityClientGadget extends EntityBaseGadget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getGadgetId() {
|
|
||||||
return configId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCampId() {
|
|
||||||
return campId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCampType() {
|
|
||||||
return campType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOwnerEntityId() {
|
|
||||||
return ownerEntityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTargetEntityId() {
|
|
||||||
return targetEntityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAsyncLoad() {
|
|
||||||
return this.asyncLoad;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOriginalOwnerEntityId() {
|
|
||||||
return this.originalOwnerEntityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeath(int killerId) {
|
public void onDeath(int killerId) {
|
||||||
super.onDeath(killerId); // Invoke super class's onDeath() method.
|
super.onDeath(killerId); // Invoke super class's onDeath() method.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public Int2FloatMap getFightProperties() {return null;}
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getPosition() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return this.pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getRotation() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return this.rot;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SceneEntityInfo toProto() {
|
public SceneEntityInfo toProto() {
|
||||||
|
@ -6,8 +6,6 @@ import emu.grasscutter.data.excels.GadgetData;
|
|||||||
import emu.grasscutter.game.entity.gadget.*;
|
import emu.grasscutter.game.entity.gadget.*;
|
||||||
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.EntityType;
|
|
||||||
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.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
||||||
@ -29,77 +27,47 @@ import emu.grasscutter.scripts.data.ScriptArgs;
|
|||||||
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
||||||
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.Int2FloatOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class EntityGadget extends EntityBaseGadget {
|
public class EntityGadget extends EntityBaseGadget {
|
||||||
private final GadgetData data;
|
@Getter private final GadgetData gadgetData;
|
||||||
private final Position pos;
|
@Getter(onMethod = @__(@Override)) @Setter
|
||||||
private final Position rot;
|
|
||||||
private int gadgetId;
|
private int gadgetId;
|
||||||
|
|
||||||
private int state;
|
@Getter @Setter private int state;
|
||||||
private int pointType;
|
@Getter @Setter private int pointType;
|
||||||
private GadgetContent content;
|
@Getter private GadgetContent content;
|
||||||
private Int2FloatOpenHashMap fightProp;
|
@Getter(onMethod = @__(@Override), lazy = true)
|
||||||
private SceneGadget metaGadget;
|
private final Int2FloatMap fightProperties = new Int2FloatOpenHashMap();
|
||||||
|
@Getter @Setter private SceneGadget metaGadget;
|
||||||
@Nullable @Getter
|
@Nullable @Getter
|
||||||
private ConfigGadget configGadget;
|
private ConfigGadget configGadget;
|
||||||
|
|
||||||
public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot) {
|
public EntityGadget(Scene scene, int gadgetId, Position pos) {
|
||||||
super(scene);
|
this(scene, gadgetId, pos, null, null);
|
||||||
this.data = GameData.getGadgetDataMap().get(gadgetId);
|
|
||||||
if (data!=null && data.getJsonName()!=null) {
|
|
||||||
this.configGadget = GameData.getGadgetConfigData().get(data.getJsonName());
|
|
||||||
}
|
|
||||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
|
||||||
this.gadgetId = gadgetId;
|
|
||||||
this.pos = pos.clone();
|
|
||||||
this.rot = rot != null ? rot.clone() : new Position();
|
|
||||||
fillFightProps(configGadget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityGadget(Scene scene, int gadgetId, Position pos) {
|
public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot) {
|
||||||
this(scene, gadgetId, pos, new Position());
|
this(scene, gadgetId, pos, rot, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot, GadgetContent content) {
|
public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot, GadgetContent content) {
|
||||||
this(scene, gadgetId, pos, rot);
|
super(scene, pos, rot);
|
||||||
this.content = content;
|
this.gadgetData = GameData.getGadgetDataMap().get(gadgetId);
|
||||||
}
|
this.configGadget = Optional.ofNullable(this.gadgetData).map(GadgetData::getJsonName).map(GameData.getGadgetConfigData()::get).orElse(null);
|
||||||
|
this.id = this.getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
||||||
public GadgetData getGadgetData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getPosition() {
|
|
||||||
return this.pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getRotation() {
|
|
||||||
return this.rot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGadgetId() {
|
|
||||||
return gadgetId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGadgetId(int gadgetId) {
|
|
||||||
this.gadgetId = gadgetId;
|
this.gadgetId = gadgetId;
|
||||||
}
|
this.content = content;
|
||||||
|
fillFightProps(configGadget);
|
||||||
public int getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(int state) {
|
|
||||||
this.state = state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateState(int state) {
|
public void updateState(int state) {
|
||||||
@ -108,39 +76,18 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
getScene().getScriptManager().callEvent(EventType.EVENT_GADGET_STATE_CHANGE, new ScriptArgs(state, this.getConfigId()));
|
getScene().getScriptManager().callEvent(EventType.EVENT_GADGET_STATE_CHANGE, new ScriptArgs(state, this.getConfigId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPointType() {
|
@Deprecated(forRemoval = true) // Dont use!
|
||||||
return pointType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPointType(int pointType) {
|
|
||||||
this.pointType = pointType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GadgetContent getContent() {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated // Dont use!
|
|
||||||
public void setContent(GadgetContent content) {
|
public void setContent(GadgetContent content) {
|
||||||
this.content = this.content == null ? content : this.content;
|
this.content = this.content == null ? content : this.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SceneGadget getMetaGadget() {
|
|
||||||
return metaGadget;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMetaGadget(SceneGadget metaGadget) {
|
|
||||||
this.metaGadget = metaGadget;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO refactor
|
// TODO refactor
|
||||||
public void buildContent() {
|
public void buildContent() {
|
||||||
if (getContent() != null || getGadgetData() == null || getGadgetData().getType() == null) {
|
if (this.getContent() != null || this.getGadgetData() == null || this.getGadgetData().getType() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityType type = getGadgetData().getType();
|
this.content = switch (this.getGadgetData().getType()) {
|
||||||
GadgetContent content = switch (type) {
|
|
||||||
case GatherPoint -> new GadgetGatherPoint(this);
|
case GatherPoint -> new GadgetGatherPoint(this);
|
||||||
case GatherObject -> new GadgetGatherObject(this);
|
case GatherObject -> new GadgetGatherObject(this);
|
||||||
case Worktop -> new GadgetWorktop(this);
|
case Worktop -> new GadgetWorktop(this);
|
||||||
@ -149,14 +96,6 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
case Gadget -> new GadgetObject(this);
|
case Gadget -> new GadgetObject(this);
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
|
||||||
if (this.fightProp == null) this.fightProp = new Int2FloatOpenHashMap();
|
|
||||||
return this.fightProp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -216,7 +155,7 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
entityInfo.addPropList(pair);
|
entityInfo.addPropList(pair);
|
||||||
|
|
||||||
// We do not use the getter to null check because the getter will create a fight prop map if it is null
|
// We do not use the getter to null check because the getter will create a fight prop map if it is null
|
||||||
if (this.fightProp != null) {
|
if (this.fightProperties != null) {
|
||||||
addAllFightPropsToEntityInfo(entityInfo);
|
addAllFightPropsToEntityInfo(entityInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,57 +25,33 @@ import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
|||||||
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
||||||
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.Int2FloatMap;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
public class EntityItem extends EntityBaseGadget {
|
public class EntityItem extends EntityBaseGadget {
|
||||||
private final Position pos;
|
@Getter private final GameItem item;
|
||||||
private final Position rot;
|
@Getter private final long guid;
|
||||||
|
@Getter private final boolean share;
|
||||||
private final GameItem item;
|
|
||||||
private final long guid;
|
|
||||||
|
|
||||||
private final boolean share;
|
|
||||||
|
|
||||||
public EntityItem(Scene scene, Player player, ItemData itemData, Position pos, int count) {
|
public EntityItem(Scene scene, Player player, ItemData itemData, Position pos, int count) {
|
||||||
super(scene);
|
this(scene, player, itemData, pos, count, true);
|
||||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
|
||||||
this.pos = new Position(pos);
|
|
||||||
this.rot = new Position();
|
|
||||||
this.guid = player == null ? scene.getWorld().getHost().getNextGameGuid() : player.getNextGameGuid();
|
|
||||||
this.item = new GameItem(itemData, count);
|
|
||||||
this.share = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// In official game, some drop items are shared to all players, and some other items are independent to all players
|
// In official game, some drop items are shared to all players, and some other items are independent to all players
|
||||||
// For example, if you killed a monster in MP mode, all players could get drops but rarity and number of them are different
|
// For example, if you killed a monster in MP mode, all players could get drops but rarity and number of them are different
|
||||||
// but if you broke regional mine, when someone picked up the drop then it disappeared
|
// but if you broke regional mine, when someone picked up the drop then it disappeared
|
||||||
public EntityItem(Scene scene, Player player, ItemData itemData, Position pos, int count, boolean share) {
|
public EntityItem(Scene scene, Player player, ItemData itemData, Position pos, int count, boolean share) {
|
||||||
super(scene);
|
super(scene, pos, null);
|
||||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
||||||
this.pos = new Position(pos);
|
|
||||||
this.rot = new Position();
|
|
||||||
this.guid = player == null ? scene.getWorld().getHost().getNextGameGuid() : player.getNextGameGuid();
|
this.guid = player == null ? scene.getWorld().getHost().getNextGameGuid() : player.getNextGameGuid();
|
||||||
this.item = new GameItem(itemData, count);
|
this.item = new GameItem(itemData, count);
|
||||||
this.share = share;
|
this.share = share;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
private GameItem getItem() {
|
|
||||||
return this.item;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemData getItemData() {
|
public ItemData getItemData() {
|
||||||
return this.getItem().getItemData();
|
return this.getItem().getItemData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getGuid() {
|
|
||||||
return guid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return this.getItem().getCount();
|
return this.getItem().getCount();
|
||||||
}
|
}
|
||||||
@ -85,24 +61,7 @@ public class EntityItem extends EntityBaseGadget {
|
|||||||
return this.getItemData().getGadgetId();
|
return this.getItemData().getGadgetId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public Int2FloatMap getFightProperties() {return null;}
|
||||||
public Position getPosition() {
|
|
||||||
return this.pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getRotation() {
|
|
||||||
return this.rot;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isShare() {
|
|
||||||
return share;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInteract(Player player, GadgetInteractReq interactReq) {
|
public void onInteract(Player player, GadgetInteractReq interactReq) {
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package emu.grasscutter.game.entity;
|
package emu.grasscutter.game.entity;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import java.util.Optional;
|
||||||
|
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
|
||||||
import emu.grasscutter.data.common.PropGrowCurve;
|
import emu.grasscutter.data.common.PropGrowCurve;
|
||||||
import emu.grasscutter.data.excels.EnvAnimalGatherConfigData;
|
import emu.grasscutter.data.excels.EnvAnimalGatherConfigData;
|
||||||
import emu.grasscutter.data.excels.ItemData;
|
|
||||||
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.inventory.GameItem;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.ActionReason;
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
import emu.grasscutter.game.props.EntityIdType;
|
import emu.grasscutter.game.props.EntityIdType;
|
||||||
@ -16,13 +14,11 @@ import emu.grasscutter.game.props.FightProperty;
|
|||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
import emu.grasscutter.net.proto.VisionTypeOuterClass;
|
|
||||||
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;
|
||||||
import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData;
|
import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData;
|
||||||
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
||||||
import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair;
|
|
||||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
||||||
import emu.grasscutter.net.proto.MonsterBornTypeOuterClass.MonsterBornType;
|
import emu.grasscutter.net.proto.MonsterBornTypeOuterClass.MonsterBornType;
|
||||||
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
||||||
@ -35,31 +31,32 @@ import emu.grasscutter.scripts.constants.EventType;
|
|||||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
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.Int2FloatOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
public class EntityMonster extends GameEntity {
|
public class EntityMonster extends GameEntity {
|
||||||
private final MonsterData monsterData;
|
@Getter private final MonsterData monsterData;
|
||||||
private final Int2FloatOpenHashMap fightProp;
|
@Getter(onMethod = @__(@Override))
|
||||||
|
private final Int2FloatOpenHashMap fightProperties;
|
||||||
|
|
||||||
private final Position pos;
|
@Getter(onMethod = @__(@Override))
|
||||||
private final Position rot;
|
private final Position position;
|
||||||
private final Position bornPos;
|
@Getter(onMethod = @__(@Override))
|
||||||
private final int level;
|
private final Position rotation;
|
||||||
|
@Getter private final Position bornPos;
|
||||||
|
@Getter private final int level;
|
||||||
private int weaponEntityId;
|
private int weaponEntityId;
|
||||||
private int poseId;
|
@Getter @Setter private int poseId;
|
||||||
@Getter @Setter
|
@Getter @Setter private int aiId = -1;
|
||||||
private int aiId=-1;
|
|
||||||
|
|
||||||
public EntityMonster(Scene scene, MonsterData monsterData, Position pos, int level) {
|
public EntityMonster(Scene scene, MonsterData monsterData, Position pos, int level) {
|
||||||
super(scene);
|
super(scene);
|
||||||
this.id = getWorld().getNextEntityId(EntityIdType.MONSTER);
|
this.id = getWorld().getNextEntityId(EntityIdType.MONSTER);
|
||||||
this.monsterData = monsterData;
|
this.monsterData = monsterData;
|
||||||
this.fightProp = new Int2FloatOpenHashMap();
|
this.fightProperties = new Int2FloatOpenHashMap();
|
||||||
this.pos = new Position(pos);
|
this.position = new Position(pos);
|
||||||
this.rot = new Position();
|
this.rotation = new Position();
|
||||||
this.bornPos = getPosition().clone();
|
this.bornPos = getPosition().clone();
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
|
||||||
@ -71,59 +68,19 @@ public class EntityMonster extends GameEntity {
|
|||||||
this.recalcStats();
|
this.recalcStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MonsterData getMonsterData() {
|
|
||||||
return monsterData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMonsterWeaponId() {
|
public int getMonsterWeaponId() {
|
||||||
return getMonsterData().getWeaponId();
|
return this.getMonsterData().getWeaponId();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMonsterId() {
|
private int getMonsterId() {
|
||||||
return this.getMonsterData().getId();
|
return this.getMonsterData().getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLevel() {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getPosition() {
|
|
||||||
return this.pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getRotation() {
|
|
||||||
return this.rot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Position getBornPos() {
|
|
||||||
return bornPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
|
||||||
return fightProp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAlive() {
|
public boolean isAlive() {
|
||||||
return this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) > 0f;
|
return this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) > 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPoseId() {
|
|
||||||
return poseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPoseId(int poseId) {
|
|
||||||
this.poseId = poseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInteract(Player player, GadgetInteractReq interactReq) {
|
public void onInteract(Player player, GadgetInteractReq interactReq) {
|
||||||
EnvAnimalGatherConfigData gatherData = GameData.getEnvAnimalGatherConfigDataMap().get(this.getMonsterData().getId());
|
EnvAnimalGatherConfigData gatherData = GameData.getEnvAnimalGatherConfigDataMap().get(this.getMonsterData().getId());
|
||||||
@ -163,27 +120,24 @@ public class EntityMonster extends GameEntity {
|
|||||||
@Override
|
@Override
|
||||||
public void onDeath(int killerId) {
|
public void onDeath(int killerId) {
|
||||||
super.onDeath(killerId); // Invoke super class's onDeath() method.
|
super.onDeath(killerId); // Invoke super class's onDeath() method.
|
||||||
|
var scene = this.getScene();
|
||||||
|
var challenge = Optional.ofNullable(scene.getChallenge());
|
||||||
|
var scriptManager = scene.getScriptManager();
|
||||||
|
|
||||||
|
Optional.ofNullable(this.getSpawnEntry()).ifPresent(scene.getDeadSpawnedEntities()::add);
|
||||||
|
|
||||||
if (this.getSpawnEntry() != null) {
|
|
||||||
this.getScene().getDeadSpawnedEntities().add(getSpawnEntry());
|
|
||||||
}
|
|
||||||
// first set the challenge data
|
// first set the challenge data
|
||||||
if (getScene().getChallenge() != null) {
|
challenge.ifPresent(c -> c.onMonsterDeath(this));
|
||||||
getScene().getChallenge().onMonsterDeath(this);
|
|
||||||
}
|
if (scriptManager.isInit() && this.getGroupId() > 0) {
|
||||||
if (getScene().getScriptManager().isInit() && this.getGroupId() > 0) {
|
Optional.ofNullable(scriptManager.getScriptMonsterSpawnService()).ifPresent(s -> s.onMonsterDead(this));
|
||||||
if (getScene().getScriptManager().getScriptMonsterSpawnService() != null) {
|
|
||||||
getScene().getScriptManager().getScriptMonsterSpawnService().onMonsterDead(this);
|
|
||||||
}
|
|
||||||
// prevent spawn monster after success
|
// prevent spawn monster after success
|
||||||
if (getScene().getChallenge() != null && getScene().getChallenge().inProgress()) {
|
if (challenge.map(c -> c.inProgress()).orElse(true))
|
||||||
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, new ScriptArgs().setParam1(this.getConfigId()));
|
scriptManager.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()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Battle Pass trigger
|
// Battle Pass trigger
|
||||||
getScene().getPlayers().forEach(p -> p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_MONSTER_DIE, this.getMonsterId(), 1));
|
scene.getPlayers().forEach(p -> p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_MONSTER_DIE, this.getMonsterId(), 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recalcStats() {
|
public void recalcStats() {
|
||||||
@ -197,18 +151,7 @@ public class EntityMonster extends GameEntity {
|
|||||||
this.getFightProperties().clear();
|
this.getFightProperties().clear();
|
||||||
|
|
||||||
// Base stats
|
// Base stats
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, data.getBaseHp());
|
MonsterData.definedFightProperties.forEach(prop -> this.setFightProperty(prop, data.getFightProperty(prop)));
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_BASE_ATTACK, data.getBaseAttack());
|
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_BASE_DEFENSE, data.getBaseDefense());
|
|
||||||
|
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT, data.getPhysicalSubHurt());
|
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_FIRE_SUB_HURT, .1f);
|
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_ELEC_SUB_HURT, data.getElecSubHurt());
|
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_WATER_SUB_HURT, data.getWaterSubHurt());
|
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_GRASS_SUB_HURT, data.getGrassSubHurt());
|
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_WIND_SUB_HURT, data.getWindSubHurt());
|
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_ROCK_SUB_HURT, .1f);
|
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_ICE_SUB_HURT, data.getIceSubHurt());
|
|
||||||
|
|
||||||
// Level curve
|
// Level curve
|
||||||
MonsterCurveData curve = GameData.getMonsterCurveDataMap().get(this.getLevel());
|
MonsterCurveData curve = GameData.getMonsterCurveDataMap().get(this.getLevel());
|
||||||
@ -220,18 +163,8 @@ public class EntityMonster extends GameEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set % stats
|
// Set % stats
|
||||||
this.setFightProperty(
|
FightProperty.forEachCompoundProperty(c -> this.setFightProperty(c.getResult(),
|
||||||
FightProperty.FIGHT_PROP_MAX_HP,
|
this.getFightProperty(c.getFlat()) + (this.getFightProperty(c.getBase()) * (1f + this.getFightProperty(c.getPercent())))));
|
||||||
(getFightProperty(FightProperty.FIGHT_PROP_BASE_HP) * (1f + getFightProperty(FightProperty.FIGHT_PROP_HP_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_HP)
|
|
||||||
);
|
|
||||||
this.setFightProperty(
|
|
||||||
FightProperty.FIGHT_PROP_CUR_ATTACK,
|
|
||||||
(getFightProperty(FightProperty.FIGHT_PROP_BASE_ATTACK) * (1f + getFightProperty(FightProperty.FIGHT_PROP_ATTACK_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_ATTACK)
|
|
||||||
);
|
|
||||||
this.setFightProperty(
|
|
||||||
FightProperty.FIGHT_PROP_CUR_DEFENSE,
|
|
||||||
(getFightProperty(FightProperty.FIGHT_PROP_BASE_DEFENSE) * (1f + getFightProperty(FightProperty.FIGHT_PROP_DEFENSE_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_DEFENSE)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set current hp
|
// Set current hp
|
||||||
this.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * hpPercent);
|
this.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * hpPercent);
|
||||||
@ -239,14 +172,14 @@ public class EntityMonster extends GameEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SceneEntityInfo toProto() {
|
public SceneEntityInfo toProto() {
|
||||||
EntityAuthorityInfo authority = EntityAuthorityInfo.newBuilder()
|
var authority = EntityAuthorityInfo.newBuilder()
|
||||||
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
|
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
|
||||||
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
|
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
|
||||||
.setAiInfo(SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(this.getBornPos().toProto()))
|
.setAiInfo(SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(this.getBornPos().toProto()))
|
||||||
.setBornPos(this.getBornPos().toProto())
|
.setBornPos(this.getBornPos().toProto())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
SceneEntityInfo.Builder entityInfo = SceneEntityInfo.newBuilder()
|
var entityInfo = SceneEntityInfo.newBuilder()
|
||||||
.setEntityId(getId())
|
.setEntityId(getId())
|
||||||
.setEntityType(ProtEntityType.PROT_ENTITY_TYPE_MONSTER)
|
.setEntityType(ProtEntityType.PROT_ENTITY_TYPE_MONSTER)
|
||||||
.setMotionInfo(this.getMotionInfo())
|
.setMotionInfo(this.getMotionInfo())
|
||||||
@ -257,13 +190,12 @@ public class EntityMonster extends GameEntity {
|
|||||||
|
|
||||||
this.addAllFightPropsToEntityInfo(entityInfo);
|
this.addAllFightPropsToEntityInfo(entityInfo);
|
||||||
|
|
||||||
PropPair pair = PropPair.newBuilder()
|
entityInfo.addPropList(PropPair.newBuilder()
|
||||||
.setType(PlayerProperty.PROP_LEVEL.getId())
|
.setType(PlayerProperty.PROP_LEVEL.getId())
|
||||||
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, getLevel()))
|
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, getLevel()))
|
||||||
.build();
|
.build());
|
||||||
entityInfo.addPropList(pair);
|
|
||||||
|
|
||||||
SceneMonsterInfo.Builder monsterInfo = SceneMonsterInfo.newBuilder()
|
var monsterInfo = SceneMonsterInfo.newBuilder()
|
||||||
.setMonsterId(getMonsterId())
|
.setMonsterId(getMonsterId())
|
||||||
.setGroupId(this.getGroupId())
|
.setGroupId(this.getGroupId())
|
||||||
.setConfigId(this.getConfigId())
|
.setConfigId(this.getConfigId())
|
||||||
|
@ -5,14 +5,16 @@ import emu.grasscutter.game.world.Scene;
|
|||||||
import emu.grasscutter.net.proto.*;
|
import emu.grasscutter.net.proto.*;
|
||||||
import emu.grasscutter.scripts.data.SceneNPC;
|
import emu.grasscutter.scripts.data.SceneNPC;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
public class EntityNPC extends GameEntity{
|
public class EntityNPC extends GameEntity{
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private final Position position;
|
private final Position position;
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private final Position rotation;
|
private final Position rotation;
|
||||||
private final SceneNPC metaNpc;
|
private final SceneNPC metaNpc;
|
||||||
private final int suiteId;
|
@Getter private final int suiteId;
|
||||||
|
|
||||||
public EntityNPC(Scene scene, SceneNPC metaNPC, int blockId, int suiteId) {
|
public EntityNPC(Scene scene, SceneNPC metaNPC, int blockId, int suiteId) {
|
||||||
super(scene);
|
super(scene);
|
||||||
@ -27,24 +29,7 @@ public class EntityNPC extends GameEntity{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public Int2FloatMap getFightProperties() {return null;}
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getRotation() {
|
|
||||||
return rotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSuiteId() {
|
|
||||||
return suiteId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
|
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
|
||||||
|
@ -5,7 +5,7 @@ import emu.grasscutter.game.world.Scene;
|
|||||||
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass;
|
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass;
|
||||||
import emu.grasscutter.scripts.data.SceneRegion;
|
import emu.grasscutter.scripts.data.SceneRegion;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -57,20 +57,11 @@ public class EntityRegion extends GameEntity{
|
|||||||
}
|
}
|
||||||
public boolean entityLeave() {return this.entityLeave;}
|
public boolean entityLeave() {return this.entityLeave;}
|
||||||
public void resetEntityLeave() {this.entityLeave = false;}
|
public void resetEntityLeave() {this.entityLeave = false;}
|
||||||
@Override
|
@Override public Int2FloatMap getFightProperties() {return null;}
|
||||||
public Int2FloatOpenHashMap getFightProperties() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override public Position getPosition() {return position;}
|
||||||
public Position getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override public Position getRotation() {return null;}
|
||||||
public Position getRotation() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
|
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
|
||||||
|
@ -12,7 +12,6 @@ import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncState
|
|||||||
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;
|
||||||
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
||||||
import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair;
|
|
||||||
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
||||||
import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType;
|
import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType;
|
||||||
@ -36,10 +35,8 @@ import java.util.List;
|
|||||||
public class EntityVehicle extends EntityBaseGadget {
|
public class EntityVehicle extends EntityBaseGadget {
|
||||||
|
|
||||||
@Getter private final Player owner;
|
@Getter private final Player owner;
|
||||||
private final Int2FloatMap fightProp;
|
@Getter(onMethod = @__(@Override))
|
||||||
|
private final Int2FloatMap fightProperties;
|
||||||
private final Position pos;
|
|
||||||
private final Position rot;
|
|
||||||
|
|
||||||
@Getter private final int pointId;
|
@Getter private final int pointId;
|
||||||
@Getter private final int gadgetId;
|
@Getter private final int gadgetId;
|
||||||
@ -49,12 +46,10 @@ public class EntityVehicle extends EntityBaseGadget {
|
|||||||
@Nullable @Getter private ConfigGadget configGadget;
|
@Nullable @Getter private ConfigGadget configGadget;
|
||||||
|
|
||||||
public EntityVehicle(Scene scene, Player player, int gadgetId, int pointId, Position pos, Position rot) {
|
public EntityVehicle(Scene scene, Player player, int gadgetId, int pointId, Position pos, Position rot) {
|
||||||
super(scene);
|
super(scene, pos, rot);
|
||||||
this.owner = player;
|
this.owner = player;
|
||||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
||||||
this.fightProp = new Int2FloatOpenHashMap();
|
this.fightProperties = new Int2FloatOpenHashMap();
|
||||||
this.pos = new Position(pos);
|
|
||||||
this.rot = new Position(rot);
|
|
||||||
this.gadgetId = gadgetId;
|
this.gadgetId = gadgetId;
|
||||||
this.pointId = pointId;
|
this.pointId = pointId;
|
||||||
this.curStamina = 240; // might be in configGadget.GCALKECLLLP.JBAKBEFIMBN.ANBMPHPOALP
|
this.curStamina = 240; // might be in configGadget.GCALKECLLLP.JBAKBEFIMBN.ANBMPHPOALP
|
||||||
@ -74,19 +69,6 @@ public class EntityVehicle extends EntityBaseGadget {
|
|||||||
this.addFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, 0);
|
this.addFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Int2FloatMap getFightProperties() {
|
|
||||||
return fightProp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getPosition() { return this.pos; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getRotation() {
|
|
||||||
return this.rot;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SceneEntityInfo toProto() {
|
public SceneEntityInfo toProto() {
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public abstract class GameEntity {
|
|||||||
@Getter @Setter private int configId;
|
@Getter @Setter private int configId;
|
||||||
@Getter @Setter private int groupId;
|
@Getter @Setter private int groupId;
|
||||||
|
|
||||||
private MotionState moveState;
|
@Getter @Setter private MotionState motionState;
|
||||||
@Getter @Setter private int lastMoveSceneTimeMs;
|
@Getter @Setter private int lastMoveSceneTimeMs;
|
||||||
@Getter @Setter private int lastMoveReliableSeq;
|
@Getter @Setter private int lastMoveReliableSeq;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ public abstract class GameEntity {
|
|||||||
|
|
||||||
public GameEntity(Scene scene) {
|
public GameEntity(Scene scene) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.moveState = MotionState.MOTION_STATE_NONE;
|
this.motionState = MotionState.MOTION_STATE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getEntityType() {
|
public int getEntityType() {
|
||||||
@ -84,14 +84,6 @@ public abstract class GameEntity {
|
|||||||
|
|
||||||
public abstract Position getRotation();
|
public abstract Position getRotation();
|
||||||
|
|
||||||
public MotionState getMotionState() {
|
|
||||||
return moveState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMotionState(MotionState moveState) {
|
|
||||||
this.moveState = moveState;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,12 @@ import javax.annotation.Nullable;
|
|||||||
public class EntityPlatform extends EntityBaseGadget {
|
public class EntityPlatform extends EntityBaseGadget {
|
||||||
@Getter
|
@Getter
|
||||||
private final Player owner;
|
private final Player owner;
|
||||||
|
@Getter(onMethod = @__(@Override))
|
||||||
private final int gadgetId;
|
private final int gadgetId;
|
||||||
@Getter
|
@Getter
|
||||||
private final EntityClientGadget gadget;
|
private final EntityClientGadget gadget;
|
||||||
private final Int2FloatMap fightProp;
|
@Getter(onMethod = @__(@Override))
|
||||||
private final Position pos;
|
private final Int2FloatMap fightProperties;
|
||||||
private final Position rot;
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Getter
|
@Getter
|
||||||
private ConfigGadget configGadget;
|
private ConfigGadget configGadget;
|
||||||
@ -39,13 +39,11 @@ public class EntityPlatform extends EntityBaseGadget {
|
|||||||
private boolean isActive;
|
private boolean isActive;
|
||||||
|
|
||||||
public EntityPlatform(EntityClientGadget gadget, Scene scene, Player player, int gadgetId, Position pos, Position rot, MovingPlatformTypeOuterClass.MovingPlatformType movingPlatformType) {
|
public EntityPlatform(EntityClientGadget gadget, Scene scene, Player player, int gadgetId, Position pos, Position rot, MovingPlatformTypeOuterClass.MovingPlatformType movingPlatformType) {
|
||||||
super(scene);
|
super(scene, pos, rot);
|
||||||
this.gadget = gadget;
|
this.gadget = gadget;
|
||||||
this.owner = player;
|
this.owner = player;
|
||||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
||||||
this.fightProp = new Int2FloatOpenHashMap();
|
this.fightProperties = new Int2FloatOpenHashMap();
|
||||||
this.pos = new Position(pos);
|
|
||||||
this.rot = new Position(rot);
|
|
||||||
this.movingPlatformType = movingPlatformType;
|
this.movingPlatformType = movingPlatformType;
|
||||||
this.gadgetId = gadgetId;
|
this.gadgetId = gadgetId;
|
||||||
GadgetData data = GameData.getGadgetDataMap().get(gadgetId);
|
GadgetData data = GameData.getGadgetDataMap().get(gadgetId);
|
||||||
@ -56,26 +54,6 @@ public class EntityPlatform extends EntityBaseGadget {
|
|||||||
fillFightProps(configGadget);
|
fillFightProps(configGadget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getGadgetId() {
|
|
||||||
return gadgetId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Int2FloatMap getFightProperties() {
|
|
||||||
return fightProp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getPosition() {
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getRotation() {
|
|
||||||
return rot;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
|
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
|
||||||
var platform = PlatformInfoOuterClass.PlatformInfo.newBuilder()
|
var platform = PlatformInfoOuterClass.PlatformInfo.newBuilder()
|
||||||
|
@ -2,6 +2,7 @@ package emu.grasscutter.game.gacha;
|
|||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.*;
|
import static emu.grasscutter.config.Configuration.*;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo;
|
import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo;
|
||||||
@ -10,65 +11,123 @@ import emu.grasscutter.utils.Utils;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
public class GachaBanner {
|
public class GachaBanner {
|
||||||
@Getter private int gachaType;
|
@Getter private int gachaType = -1;
|
||||||
@Getter private int scheduleId;
|
@Getter int scheduleId = -1;
|
||||||
|
@Getter int sortId = -1;
|
||||||
@Getter private String prefabPath;
|
@Getter private String prefabPath;
|
||||||
private String previewPrefabPath;
|
@Getter private String previewPrefabPath;
|
||||||
@Getter private String titlePath;
|
@Getter private String titlePath;
|
||||||
private int costItemId = 0;
|
private int costItemId = 0;
|
||||||
private int costItemAmount = 1;
|
private int costItemAmount = 1;
|
||||||
private int costItemId10 = 0;
|
private int costItemId10 = 0;
|
||||||
private int costItemAmount10 = 10;
|
private int costItemAmount10 = 10;
|
||||||
@Getter private int beginTime;
|
@Getter private int beginTime = 0;
|
||||||
@Getter private int endTime;
|
@Getter private int endTime = 1924992000;
|
||||||
@Getter private int sortId;
|
|
||||||
@Getter private int gachaTimesLimit = Integer.MAX_VALUE;
|
@Getter private int gachaTimesLimit = Integer.MAX_VALUE;
|
||||||
private int[] rateUpItems4 = {};
|
@Getter private int[] rateUpItems4 = {};
|
||||||
private int[] rateUpItems5 = {};
|
@Getter private int[] rateUpItems5 = {};
|
||||||
@Getter private int[] fallbackItems3 = {11301, 11302, 11306, 12301, 12302, 12305, 13303, 14301, 14302, 14304, 15301, 15302, 15304};
|
// This now handles default values for the fields below
|
||||||
@Getter private int[] fallbackItems4Pool1 = {1014, 1020, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1064};
|
|
||||||
@Getter private int[] fallbackItems4Pool2 = {11401, 11402, 11403, 11405, 12401, 12402, 12403, 12405, 13401, 13407, 14401, 14402, 14403, 14409, 15401, 15402, 15403, 15405};
|
|
||||||
@Getter private int[] fallbackItems5Pool1 = {1003, 1016, 1042, 1035, 1041};
|
|
||||||
@Getter private int[] fallbackItems5Pool2 = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502};
|
|
||||||
@Getter private boolean removeC6FromPool = false;
|
|
||||||
@Getter private boolean autoStripRateUpFromFallback = true;
|
|
||||||
private int[][] weights4 = {{1,510}, {8,510}, {10,10000}};
|
|
||||||
private int[][] weights5 = {{1,75}, {73,150}, {90,10000}};
|
|
||||||
private int[][] poolBalanceWeights4 = {{1,255}, {17,255}, {21,10455}};
|
|
||||||
private int[][] poolBalanceWeights5 = {{1,30}, {147,150}, {181,10230}};
|
|
||||||
private int eventChance4 = 50; // Chance to win a featured event item
|
|
||||||
private int eventChance5 = 50; // Chance to win a featured event item
|
|
||||||
@Getter private BannerType bannerType = BannerType.STANDARD;
|
@Getter private BannerType bannerType = BannerType.STANDARD;
|
||||||
|
// Constants used by the BannerType enum
|
||||||
// Kinda wanna deprecate these but they're in people's configs
|
static final int[][] DEFAULT_WEIGHTS_4 = {{1,510}, {8,510}, {10,10000}};
|
||||||
private int[] rateUpItems1 = {};
|
static final int[][] DEFAULT_WEIGHTS_4_WEAPON = {{1, 600}, {7, 600}, {8, 6600}, {10, 12600}};
|
||||||
private int[] rateUpItems2 = {};
|
static final int[][] DEFAULT_WEIGHTS_5 = {{1,75}, {73,150}, {90,10000}};
|
||||||
private int eventChance = -1;
|
static final int[][] DEFAULT_WEIGHTS_5_CHARACTER = {{1,80}, {73,80}, {90,10000}};
|
||||||
private int costItem = 0;
|
static final int[][] DEFAULT_WEIGHTS_5_WEAPON = {{1,100}, {62,100}, {73,7800}, {80,10000}};
|
||||||
|
static final int[] DEFAULT_FALLBACK_ITEMS_4_POOL_1 = {1014, 1020, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1059, 1064, 1065, 1067, 1068, 1072}; // Default avatars
|
||||||
|
static final int[] DEFAULT_FALLBACK_ITEMS_4_POOL_2 = {11401, 11402, 11403, 11405, 12401, 12402, 12403, 12405, 13401, 13407, 14401, 14402, 14403, 14409, 15401, 15402, 15403, 15405}; // Default weapons
|
||||||
|
static final int[] DEFAULT_FALLBACK_ITEMS_5_POOL_1 = {1003, 1016, 1042, 1035, 1041, 1069}; // Default avatars
|
||||||
|
static final int[] DEFAULT_FALLBACK_ITEMS_5_POOL_2 = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502}; // Default weapons
|
||||||
|
static final int[] EMPTY_POOL = {}; // Used to remove a type of fallback
|
||||||
|
// These don't change between banner types (apart from Standard having three extra 4star avatars)
|
||||||
|
@Getter private int[] fallbackItems3 = {11301, 11302, 11306, 12301, 12302, 12305, 13303, 14301, 14302, 14304, 15301, 15302, 15304};
|
||||||
|
@Getter private int[] fallbackItems4Pool1 = DEFAULT_FALLBACK_ITEMS_4_POOL_1;
|
||||||
|
@Getter private int[] fallbackItems4Pool2 = DEFAULT_FALLBACK_ITEMS_4_POOL_2;
|
||||||
|
// Different banner types have different defaults, see above for default values and the enum for which are used where.
|
||||||
|
@Getter private int[] fallbackItems5Pool1;
|
||||||
|
@Getter private int[] fallbackItems5Pool2;
|
||||||
|
private int[][] weights4;
|
||||||
|
private int[][] weights5;
|
||||||
|
private int eventChance4 = -1; // Chance to win a featured event item
|
||||||
|
private int eventChance5 = -1; // Chance to win a featured event item
|
||||||
|
//
|
||||||
|
@Getter private boolean removeC6FromPool = false;
|
||||||
|
@Getter private boolean autoStripRateUpFromFallback = true; // Ensures that featured items won't "double dip" into the losing pool
|
||||||
|
private int[][] poolBalanceWeights4 = {{1,255}, {17,255}, {21,10455}}; // Used to ensure that players won't go too many rolls without getting something from pool 1 (avatar) or pool 2 (weapon)
|
||||||
|
private int[][] poolBalanceWeights5 = {{1,30}, {147,150}, {181,10230}};
|
||||||
@Getter private int wishMaxProgress = 2;
|
@Getter private int wishMaxProgress = 2;
|
||||||
|
|
||||||
public String getPreviewPrefabPath() {
|
// Deprecated fields that were tolerated in early May 2022 but have apparently still being circulating in new custom configs
|
||||||
if (this.previewPrefabPath != null && !this.previewPrefabPath.isEmpty())
|
// For now, throw up big scary errors on load telling people that they will be banned outright in a future version
|
||||||
return this.previewPrefabPath;
|
@Deprecated private int[] rateUpItems1 = {};
|
||||||
return "UI_Tab_" + this.prefabPath;
|
@Deprecated private int[] rateUpItems2 = {};
|
||||||
|
@Deprecated private int eventChance = -1;
|
||||||
|
@Deprecated private int costItem = 0;
|
||||||
|
@Deprecated private int softPity = -1;
|
||||||
|
@Deprecated private int hardPity = -1;
|
||||||
|
@Deprecated private int minItemType = -1;
|
||||||
|
@Deprecated private int maxItemType = -1;
|
||||||
|
@Getter private boolean deprecated = false;
|
||||||
|
@Getter private boolean disabled = false;
|
||||||
|
|
||||||
|
private void warnDeprecated(String name, String replacement) {
|
||||||
|
Grasscutter.getLogger().error("Deprecated field found in Banners config: "+name+" was replaced back in early May 2022, use "+replacement+" instead. You MUST remove this field from your config.");
|
||||||
|
this.deprecated = true;
|
||||||
|
}
|
||||||
|
public void onLoad() {
|
||||||
|
// Handle deprecated configs
|
||||||
|
if (eventChance != -1)
|
||||||
|
warnDeprecated("eventChance", "eventChance4 & eventChance5");
|
||||||
|
if (costItem != 0)
|
||||||
|
warnDeprecated("costItem", "costItemId");
|
||||||
|
if (softPity != -1)
|
||||||
|
warnDeprecated("softPity", "weights5");
|
||||||
|
if (hardPity != -1)
|
||||||
|
warnDeprecated("hardPity", "weights5");
|
||||||
|
if (minItemType != -1)
|
||||||
|
warnDeprecated("minItemType", "fallbackItems[4,5]Pool[1,2]");
|
||||||
|
if (maxItemType != -1)
|
||||||
|
warnDeprecated("maxItemType", "fallbackItems[4,5]Pool[1,2]");
|
||||||
|
if (rateUpItems1.length > 0)
|
||||||
|
warnDeprecated("rateUpItems1", "rateUpItems5");
|
||||||
|
if (rateUpItems2.length > 0)
|
||||||
|
warnDeprecated("rateUpItems2", "rateUpItems4");
|
||||||
|
|
||||||
|
// Handle default values
|
||||||
|
if (this.previewPrefabPath != null && this.previewPrefabPath.equals("UI_Tab_" + this.prefabPath))
|
||||||
|
Grasscutter.getLogger().error("Redundant field found in Banners config: previewPrefabPath does not need to be specified if it is identical to prefabPath prefixed with \"UI_Tab_\".");
|
||||||
|
if (this.previewPrefabPath == null || this.previewPrefabPath.isEmpty())
|
||||||
|
this.previewPrefabPath = "UI_Tab_" + this.prefabPath;
|
||||||
|
if (this.gachaType < 0)
|
||||||
|
this.gachaType = this.bannerType.gachaType;
|
||||||
|
if (this.costItemId == 0)
|
||||||
|
this.costItemId = this.bannerType.costItemId;
|
||||||
|
if (this.costItemId10 == 0)
|
||||||
|
this.costItemId10 = this.costItemId;
|
||||||
|
if (this.weights4 == null)
|
||||||
|
this.weights4 = this.bannerType.weights4;
|
||||||
|
if (this.weights5 == null)
|
||||||
|
this.weights5 = this.bannerType.weights5;
|
||||||
|
if (this.eventChance4 < 0)
|
||||||
|
this.eventChance4 = this.bannerType.eventChance4;
|
||||||
|
if (this.eventChance5 < 0)
|
||||||
|
this.eventChance5 = this.bannerType.eventChance5;
|
||||||
|
if (this.fallbackItems5Pool1 == null)
|
||||||
|
this.fallbackItems5Pool1 = this.bannerType.fallbackItems5Pool1;
|
||||||
|
if (this.fallbackItems5Pool2 == null)
|
||||||
|
this.fallbackItems5Pool2 = this.bannerType.fallbackItems5Pool2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemParamData getCost(int numRolls) {
|
public ItemParamData getCost(int numRolls) {
|
||||||
return switch (numRolls) {
|
return switch (numRolls) {
|
||||||
case 10 -> new ItemParamData((costItemId10 > 0) ? costItemId10 : getCostItem(), costItemAmount10);
|
case 10 -> new ItemParamData(costItemId10, costItemAmount10);
|
||||||
default -> new ItemParamData(getCostItem(), costItemAmount * numRolls);
|
default -> new ItemParamData(costItemId, costItemAmount * numRolls);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public int getCostItem() {
|
public int getCostItem() {
|
||||||
return (costItem > 0) ? costItem : costItemId;
|
return costItemId;
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getRateUpItems4() {
|
|
||||||
return (rateUpItems2.length > 0) ? rateUpItems2 : rateUpItems4;
|
|
||||||
}
|
|
||||||
public int[] getRateUpItems5() {
|
|
||||||
return (rateUpItems1.length > 0) ? rateUpItems1 : rateUpItems5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasEpitomized() {
|
public boolean hasEpitomized() {
|
||||||
@ -92,7 +151,7 @@ public class GachaBanner {
|
|||||||
public int getEventChance(int rarity) {
|
public int getEventChance(int rarity) {
|
||||||
return switch (rarity) {
|
return switch (rarity) {
|
||||||
case 4 -> eventChance4;
|
case 4 -> eventChance4;
|
||||||
default -> (eventChance > -1) ? eventChance : eventChance5;
|
default -> eventChance5;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,8 +169,6 @@ public class GachaBanner {
|
|||||||
+ "/gacha/details?s=" + sessionKey + "&scheduleId=" + scheduleId;
|
+ "/gacha/details?s=" + sessionKey + "&scheduleId=" + scheduleId;
|
||||||
|
|
||||||
// Grasscutter.getLogger().info("record = " + record);
|
// Grasscutter.getLogger().info("record = " + record);
|
||||||
ItemParamData costItem1 = this.getCost(1);
|
|
||||||
ItemParamData costItem10 = this.getCost(10);
|
|
||||||
PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(this);
|
PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(this);
|
||||||
int leftGachaTimes = switch (gachaTimesLimit) {
|
int leftGachaTimes = switch (gachaTimesLimit) {
|
||||||
case Integer.MAX_VALUE -> Integer.MAX_VALUE;
|
case Integer.MAX_VALUE -> Integer.MAX_VALUE;
|
||||||
@ -122,10 +179,10 @@ public class GachaBanner {
|
|||||||
.setScheduleId(this.getScheduleId())
|
.setScheduleId(this.getScheduleId())
|
||||||
.setBeginTime(this.getBeginTime())
|
.setBeginTime(this.getBeginTime())
|
||||||
.setEndTime(this.getEndTime())
|
.setEndTime(this.getEndTime())
|
||||||
.setCostItemId(costItem1.getId())
|
.setCostItemId(this.costItemId)
|
||||||
.setCostItemNum(costItem1.getCount())
|
.setCostItemNum(this.costItemAmount)
|
||||||
.setTenCostItemId(costItem10.getId())
|
.setTenCostItemId(this.costItemId10)
|
||||||
.setTenCostItemNum(costItem10.getCount())
|
.setTenCostItemNum(this.costItemAmount10)
|
||||||
.setGachaPrefabPath(this.getPrefabPath())
|
.setGachaPrefabPath(this.getPrefabPath())
|
||||||
.setGachaPreviewPrefabPath(this.getPreviewPrefabPath())
|
.setGachaPreviewPrefabPath(this.getPreviewPrefabPath())
|
||||||
.setGachaProbUrl(details)
|
.setGachaProbUrl(details)
|
||||||
@ -174,6 +231,31 @@ public class GachaBanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum BannerType {
|
public enum BannerType {
|
||||||
STANDARD, EVENT, WEAPON;
|
STANDARD(200, 224, DEFAULT_WEIGHTS_4, DEFAULT_WEIGHTS_5, 50, 50, DEFAULT_FALLBACK_ITEMS_5_POOL_1, DEFAULT_FALLBACK_ITEMS_5_POOL_2),
|
||||||
|
BEGINNER(100, 224, DEFAULT_WEIGHTS_4, DEFAULT_WEIGHTS_5, 50, 50, DEFAULT_FALLBACK_ITEMS_5_POOL_1, DEFAULT_FALLBACK_ITEMS_5_POOL_2),
|
||||||
|
EVENT(301, 223, DEFAULT_WEIGHTS_4, DEFAULT_WEIGHTS_5_CHARACTER, 50, 50, DEFAULT_FALLBACK_ITEMS_5_POOL_1, DEFAULT_FALLBACK_ITEMS_5_POOL_2), // Legacy value for CHARACTER
|
||||||
|
CHARACTER(301, 223, DEFAULT_WEIGHTS_4, DEFAULT_WEIGHTS_5_CHARACTER, 50, 50, DEFAULT_FALLBACK_ITEMS_5_POOL_1, EMPTY_POOL),
|
||||||
|
CHARACTER2(400, 223, DEFAULT_WEIGHTS_4, DEFAULT_WEIGHTS_5_CHARACTER, 50, 50, DEFAULT_FALLBACK_ITEMS_5_POOL_1, EMPTY_POOL),
|
||||||
|
WEAPON(302, 223, DEFAULT_WEIGHTS_4_WEAPON, DEFAULT_WEIGHTS_5_WEAPON, 75, 75, EMPTY_POOL, DEFAULT_FALLBACK_ITEMS_5_POOL_2);
|
||||||
|
|
||||||
|
public final int gachaType;
|
||||||
|
public final int costItemId;
|
||||||
|
public final int[][] weights4;
|
||||||
|
public final int[][] weights5;
|
||||||
|
public final int eventChance4;
|
||||||
|
public final int eventChance5;
|
||||||
|
public final int[] fallbackItems5Pool1;
|
||||||
|
public final int[] fallbackItems5Pool2;
|
||||||
|
|
||||||
|
BannerType(int gachaType, int costItemId, int[][] weights4, int[][] weights5, int eventChance4, int eventChance5, int[] fallbackItems5Pool1, int[] fallbackItems5Pool2) {
|
||||||
|
this.gachaType = gachaType;
|
||||||
|
this.costItemId = costItemId;
|
||||||
|
this.weights4 = weights4;
|
||||||
|
this.weights5 = weights5;
|
||||||
|
this.eventChance4 = eventChance4;
|
||||||
|
this.eventChance5 = eventChance5;
|
||||||
|
this.fallbackItems5Pool1 = fallbackItems5Pool1;
|
||||||
|
this.fallbackItems5Pool2 = fallbackItems5Pool2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,6 @@ public class GachaSystem extends BaseGameSystem {
|
|||||||
|
|
||||||
private static final int starglitterId = 221;
|
private static final int starglitterId = 221;
|
||||||
private static final int stardustId = 222;
|
private static final int stardustId = 222;
|
||||||
private int[] fallbackItems4Pool2Default = {11401, 11402, 11403, 11405, 12401, 12402, 12403, 12405, 13401, 13407, 14401, 14402, 14403, 14409, 15401, 15402, 15403, 15405};
|
|
||||||
private int[] fallbackItems5Pool2Default = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502};
|
|
||||||
|
|
||||||
public GachaSystem(GameServer server) {
|
public GachaSystem(GameServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
@ -69,11 +67,24 @@ public class GachaSystem extends BaseGameSystem {
|
|||||||
|
|
||||||
public synchronized void load() {
|
public synchronized void load() {
|
||||||
getGachaBanners().clear();
|
getGachaBanners().clear();
|
||||||
|
int autoScheduleId = 1000;
|
||||||
|
int autoSortId = 9000;
|
||||||
try {
|
try {
|
||||||
List<GachaBanner> banners = DataLoader.loadList("Banners.json", GachaBanner.class);
|
List<GachaBanner> banners = DataLoader.loadTableToList("Banners", GachaBanner.class);
|
||||||
if (banners.size() > 0) {
|
if (banners.size() > 0) {
|
||||||
for (GachaBanner banner : banners) {
|
for (GachaBanner banner : banners) {
|
||||||
getGachaBanners().put(banner.getScheduleId(), banner);
|
banner.onLoad();
|
||||||
|
if (banner.isDeprecated()) {
|
||||||
|
Grasscutter.getLogger().error("A Banner has not been loaded because it contains one or more deprecated fields. Remove the fields mentioned above and reload.");
|
||||||
|
} else if (banner.isDisabled()) {
|
||||||
|
Grasscutter.getLogger().debug("A Banner has not been loaded because it is disabled.");
|
||||||
|
} else {
|
||||||
|
if (banner.scheduleId < 0)
|
||||||
|
banner.scheduleId = autoScheduleId++;
|
||||||
|
if (banner.sortId < 0)
|
||||||
|
banner.sortId = autoSortId--;
|
||||||
|
getGachaBanners().put(banner.scheduleId, banner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Grasscutter.getLogger().debug("Banners successfully loaded.");
|
Grasscutter.getLogger().debug("Banners successfully loaded.");
|
||||||
} else {
|
} else {
|
||||||
@ -155,7 +166,7 @@ public class GachaSystem extends BaseGameSystem {
|
|||||||
private synchronized int doFallbackRarePull(int[] fallback1, int[] fallback2, int rarity, GachaBanner banner, PlayerGachaBannerInfo gachaInfo) {
|
private synchronized int doFallbackRarePull(int[] fallback1, int[] fallback2, int rarity, GachaBanner banner, PlayerGachaBannerInfo gachaInfo) {
|
||||||
if (fallback1.length < 1) {
|
if (fallback1.length < 1) {
|
||||||
if (fallback2.length < 1) {
|
if (fallback2.length < 1) {
|
||||||
return getRandom((rarity==5)? fallbackItems5Pool2Default : fallbackItems4Pool2Default);
|
return getRandom((rarity==5)? GachaBanner.DEFAULT_FALLBACK_ITEMS_5_POOL_2 : GachaBanner.DEFAULT_FALLBACK_ITEMS_4_POOL_2);
|
||||||
} else {
|
} else {
|
||||||
return getRandom(fallback2);
|
return getRandom(fallback2);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import dev.morphia.annotations.Entity;
|
|||||||
@Entity
|
@Entity
|
||||||
public class PlayerGachaInfo {
|
public class PlayerGachaInfo {
|
||||||
private PlayerGachaBannerInfo standardBanner;
|
private PlayerGachaBannerInfo standardBanner;
|
||||||
|
private PlayerGachaBannerInfo beginnerBanner;
|
||||||
private PlayerGachaBannerInfo eventCharacterBanner;
|
private PlayerGachaBannerInfo eventCharacterBanner;
|
||||||
private PlayerGachaBannerInfo eventWeaponBanner;
|
private PlayerGachaBannerInfo eventWeaponBanner;
|
||||||
|
|
||||||
@ -15,26 +16,31 @@ public class PlayerGachaInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PlayerGachaBannerInfo getStandardBanner() {
|
public PlayerGachaBannerInfo getStandardBanner() {
|
||||||
return standardBanner;
|
if (this.standardBanner == null) this.standardBanner = new PlayerGachaBannerInfo();
|
||||||
|
return this.standardBanner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerGachaBannerInfo getBeginnerBanner() {
|
||||||
|
if (this.beginnerBanner == null) this.beginnerBanner = new PlayerGachaBannerInfo();
|
||||||
|
return this.beginnerBanner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerGachaBannerInfo getEventCharacterBanner() {
|
public PlayerGachaBannerInfo getEventCharacterBanner() {
|
||||||
return eventCharacterBanner;
|
if (this.eventCharacterBanner == null) this.eventCharacterBanner = new PlayerGachaBannerInfo();
|
||||||
|
return this.eventCharacterBanner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerGachaBannerInfo getEventWeaponBanner() {
|
public PlayerGachaBannerInfo getEventWeaponBanner() {
|
||||||
return eventWeaponBanner;
|
if (this.eventWeaponBanner == null) this.eventWeaponBanner = new PlayerGachaBannerInfo();
|
||||||
|
return this.eventWeaponBanner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerGachaBannerInfo getBannerInfo(GachaBanner banner) {
|
public PlayerGachaBannerInfo getBannerInfo(GachaBanner banner) {
|
||||||
switch (banner.getBannerType()) {
|
return switch (banner.getBannerType()) {
|
||||||
case EVENT:
|
case STANDARD -> this.getStandardBanner();
|
||||||
return this.eventCharacterBanner;
|
case BEGINNER -> this.getBeginnerBanner();
|
||||||
case WEAPON:
|
case EVENT, CHARACTER, CHARACTER2 -> this.getEventCharacterBanner();
|
||||||
return this.eventWeaponBanner;
|
case WEAPON -> this.getEventWeaponBanner();
|
||||||
case STANDARD:
|
};
|
||||||
default:
|
|
||||||
return this.standardBanner;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,6 +181,7 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
|||||||
|
|
||||||
if (data.isUseOnGain()) {
|
if (data.isUseOnGain()) {
|
||||||
var params = new UseItemParams(this.player, data.getUseTarget());
|
var params = new UseItemParams(this.player, data.getUseTarget());
|
||||||
|
params.usedItemId = data.getId();
|
||||||
this.player.getServer().getInventorySystem().useItemDirect(data, params);
|
this.player.getServer().getInventorySystem().useItemDirect(data, params);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,11 @@ public class DeforestationManager extends BasePlayerManager {
|
|||||||
ColliderTypeToWoodItemID.put(10,101310);
|
ColliderTypeToWoodItemID.put(10,101310);
|
||||||
ColliderTypeToWoodItemID.put(11,101311);
|
ColliderTypeToWoodItemID.put(11,101311);
|
||||||
ColliderTypeToWoodItemID.put(12,101312);
|
ColliderTypeToWoodItemID.put(12,101312);
|
||||||
|
ColliderTypeToWoodItemID.put(13,101313);
|
||||||
|
ColliderTypeToWoodItemID.put(14,101314);
|
||||||
|
ColliderTypeToWoodItemID.put(15,101315);
|
||||||
|
ColliderTypeToWoodItemID.put(16,101316);
|
||||||
|
ColliderTypeToWoodItemID.put(17,101317);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeforestationManager(Player player) {
|
public DeforestationManager(Player player) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package emu.grasscutter.game.player;
|
package emu.grasscutter.game.player;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -15,11 +15,8 @@ import emu.grasscutter.server.packet.send.PacketServerBuffChangeNotify;
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.val;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PRIVATE)
|
|
||||||
public class PlayerBuffManager extends BasePlayerManager {
|
public class PlayerBuffManager extends BasePlayerManager {
|
||||||
private int nextBuffUid;
|
private int nextBuffUid;
|
||||||
|
|
||||||
@ -29,7 +26,7 @@ public class PlayerBuffManager extends BasePlayerManager {
|
|||||||
public PlayerBuffManager(Player player) {
|
public PlayerBuffManager(Player player) {
|
||||||
super(player);
|
super(player);
|
||||||
this.buffs = new Int2ObjectOpenHashMap<>();
|
this.buffs = new Int2ObjectOpenHashMap<>();
|
||||||
this.pendingBuffs = new LinkedList<>();
|
this.pendingBuffs = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +43,7 @@ public class PlayerBuffManager extends BasePlayerManager {
|
|||||||
* @return True if a buff with this group id exists
|
* @return True if a buff with this group id exists
|
||||||
*/
|
*/
|
||||||
public synchronized boolean hasBuff(int groupId) {
|
public synchronized boolean hasBuff(int groupId) {
|
||||||
return this.getBuffs().containsKey(groupId);
|
return this.buffs.containsKey(groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,11 +52,11 @@ public class PlayerBuffManager extends BasePlayerManager {
|
|||||||
public synchronized void clearBuffs() {
|
public synchronized void clearBuffs() {
|
||||||
// Remove from player
|
// Remove from player
|
||||||
getPlayer().sendPacket(
|
getPlayer().sendPacket(
|
||||||
new PacketServerBuffChangeNotify(getPlayer(), ServerBuffChangeType.SERVER_BUFF_CHANGE_TYPE_DEL_SERVER_BUFF, getBuffs().values())
|
new PacketServerBuffChangeNotify(getPlayer(), ServerBuffChangeType.SERVER_BUFF_CHANGE_TYPE_DEL_SERVER_BUFF, this.buffs.values())
|
||||||
);
|
);
|
||||||
|
|
||||||
// Clear
|
// Clear
|
||||||
getBuffs().clear();
|
this.buffs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,13 +130,11 @@ public class PlayerBuffManager extends BasePlayerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear previous buff if it exists
|
// Clear previous buff if it exists
|
||||||
if (this.hasBuff(buffData.getGroupId())) {
|
|
||||||
this.removeBuff(buffData.getGroupId());
|
this.removeBuff(buffData.getGroupId());
|
||||||
}
|
|
||||||
|
|
||||||
// Create and store buff
|
// Create and store buff
|
||||||
PlayerBuff buff = new PlayerBuff(getNextBuffUid(), buffData, duration);
|
PlayerBuff buff = new PlayerBuff(getNextBuffUid(), buffData, duration);
|
||||||
getBuffs().put(buff.getGroupId(), buff);
|
this.buffs.put(buff.getGroupId(), buff);
|
||||||
|
|
||||||
// Packet
|
// Packet
|
||||||
getPlayer().sendPacket(new PacketServerBuffChangeNotify(getPlayer(), ServerBuffChangeType.SERVER_BUFF_CHANGE_TYPE_ADD_SERVER_BUFF, buff));
|
getPlayer().sendPacket(new PacketServerBuffChangeNotify(getPlayer(), ServerBuffChangeType.SERVER_BUFF_CHANGE_TYPE_ADD_SERVER_BUFF, buff));
|
||||||
@ -153,7 +148,7 @@ public class PlayerBuffManager extends BasePlayerManager {
|
|||||||
* @return True if a buff was remove
|
* @return True if a buff was remove
|
||||||
*/
|
*/
|
||||||
public synchronized boolean removeBuff(int buffGroupId) {
|
public synchronized boolean removeBuff(int buffGroupId) {
|
||||||
PlayerBuff buff = this.getBuffs().get(buffGroupId);
|
PlayerBuff buff = this.buffs.remove(buffGroupId);
|
||||||
|
|
||||||
if (buff != null) {
|
if (buff != null) {
|
||||||
getPlayer().sendPacket(
|
getPlayer().sendPacket(
|
||||||
@ -167,28 +162,24 @@ public class PlayerBuffManager extends BasePlayerManager {
|
|||||||
|
|
||||||
public synchronized void onTick() {
|
public synchronized void onTick() {
|
||||||
// Skip if no buffs
|
// Skip if no buffs
|
||||||
if (getBuffs().size() == 0) return;
|
if (this.buffs.isEmpty()) return;
|
||||||
|
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
|
|
||||||
// Add to pending buffs to remove if buff has expired
|
// Add to pending buffs to remove if buff has expired
|
||||||
for (PlayerBuff buff : getBuffs().values()) {
|
this.buffs.values().removeIf(buff -> {
|
||||||
if (currentTime > buff.getEndTime()) {
|
if (currentTime <= buff.getEndTime())
|
||||||
this.getPendingBuffs().add(buff);
|
return false;
|
||||||
}
|
this.pendingBuffs.add(buff);
|
||||||
}
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
if (this.getPendingBuffs().size() > 0) {
|
if (this.pendingBuffs.size() > 0) {
|
||||||
// Send packet
|
// Send packet
|
||||||
getPlayer().sendPacket(
|
getPlayer().sendPacket(
|
||||||
new PacketServerBuffChangeNotify(getPlayer(), ServerBuffChangeType.SERVER_BUFF_CHANGE_TYPE_DEL_SERVER_BUFF, this.pendingBuffs)
|
new PacketServerBuffChangeNotify(getPlayer(), ServerBuffChangeType.SERVER_BUFF_CHANGE_TYPE_DEL_SERVER_BUFF, this.pendingBuffs)
|
||||||
);
|
);
|
||||||
|
this.pendingBuffs.clear();
|
||||||
// Remove buff from player buff map
|
|
||||||
for (PlayerBuff buff : this.getPendingBuffs()) {
|
|
||||||
getBuffs().remove(buff.getGroupId());
|
|
||||||
}
|
|
||||||
this.getPendingBuffs().clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
public enum FightProperty {
|
public enum FightProperty {
|
||||||
FIGHT_PROP_NONE(0),
|
FIGHT_PROP_NONE(0),
|
||||||
@ -197,6 +199,35 @@ public enum FightProperty {
|
|||||||
FIGHT_PROP_CUR_WATER_ENERGY, FIGHT_PROP_CUR_GRASS_ENERGY, FIGHT_PROP_CUR_WIND_ENERGY, FIGHT_PROP_CUR_ICE_ENERGY,
|
FIGHT_PROP_CUR_WATER_ENERGY, FIGHT_PROP_CUR_GRASS_ENERGY, FIGHT_PROP_CUR_WIND_ENERGY, FIGHT_PROP_CUR_ICE_ENERGY,
|
||||||
FIGHT_PROP_CUR_ROCK_ENERGY, FIGHT_PROP_CUR_HP, FIGHT_PROP_MAX_HP, FIGHT_PROP_CUR_ATTACK, FIGHT_PROP_CUR_DEFENSE);
|
FIGHT_PROP_CUR_ROCK_ENERGY, FIGHT_PROP_CUR_HP, FIGHT_PROP_MAX_HP, FIGHT_PROP_CUR_ATTACK, FIGHT_PROP_CUR_DEFENSE);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public static class CompoundProperty {
|
||||||
|
private FightProperty result;
|
||||||
|
private FightProperty base;
|
||||||
|
private FightProperty percent;
|
||||||
|
private FightProperty flat;
|
||||||
|
|
||||||
|
public CompoundProperty(FightProperty result, FightProperty base, FightProperty percent, FightProperty flat) {
|
||||||
|
this.result = result;
|
||||||
|
this.base = base;
|
||||||
|
this.percent = percent;
|
||||||
|
this.flat = flat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<FightProperty, CompoundProperty> compoundProperties = Map.ofEntries(
|
||||||
|
entry(FIGHT_PROP_MAX_HP, new CompoundProperty(FIGHT_PROP_MAX_HP, FIGHT_PROP_BASE_HP, FIGHT_PROP_HP_PERCENT, FIGHT_PROP_HP)),
|
||||||
|
entry(FIGHT_PROP_CUR_ATTACK, new CompoundProperty(FIGHT_PROP_CUR_ATTACK, FIGHT_PROP_BASE_ATTACK, FIGHT_PROP_ATTACK_PERCENT, FIGHT_PROP_ATTACK)),
|
||||||
|
entry(FIGHT_PROP_CUR_DEFENSE, new CompoundProperty(FIGHT_PROP_CUR_DEFENSE, FIGHT_PROP_BASE_DEFENSE, FIGHT_PROP_DEFENSE_PERCENT, FIGHT_PROP_DEFENSE))
|
||||||
|
);
|
||||||
|
|
||||||
|
public static CompoundProperty getCompoundProperty(FightProperty result) {
|
||||||
|
return compoundProperties.get(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void forEachCompoundProperty(Consumer<CompoundProperty> consumer) {
|
||||||
|
compoundProperties.values().forEach(consumer);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isPercentage(FightProperty prop) {
|
public static boolean isPercentage(FightProperty prop) {
|
||||||
return !flatProps.contains(prop);
|
return !flatProps.contains(prop);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public class ItemUseAction {
|
|||||||
case ITEM_USE_GAIN_AVATAR -> new ItemUseGainAvatar(useParam);
|
case ITEM_USE_GAIN_AVATAR -> new ItemUseGainAvatar(useParam);
|
||||||
case ITEM_USE_GAIN_COSTUME -> new ItemUseGainCostume(useParam); // TODO - real success/fail
|
case ITEM_USE_GAIN_COSTUME -> new ItemUseGainCostume(useParam); // TODO - real success/fail
|
||||||
case ITEM_USE_GAIN_FLYCLOAK -> new ItemUseGainFlycloak(useParam); // TODO - real success/fail
|
case ITEM_USE_GAIN_FLYCLOAK -> new ItemUseGainFlycloak(useParam); // TODO - real success/fail
|
||||||
case ITEM_USE_GAIN_NAME_CARD -> new ItemUseGainNameCard(useParam); // TODO
|
case ITEM_USE_GAIN_NAME_CARD -> new ItemUseGainNameCard(useParam);
|
||||||
case ITEM_USE_CHEST_SELECT_ITEM -> new ItemUseChestSelectItem(useParam);
|
case ITEM_USE_CHEST_SELECT_ITEM -> new ItemUseChestSelectItem(useParam);
|
||||||
case ITEM_USE_ADD_SELECT_ITEM -> new ItemUseAddSelectItem(useParam);
|
case ITEM_USE_ADD_SELECT_ITEM -> new ItemUseAddSelectItem(useParam);
|
||||||
case ITEM_USE_GRANT_SELECT_REWARD -> new ItemUseGrantSelectReward(useParam);
|
case ITEM_USE_GRANT_SELECT_REWARD -> new ItemUseGrantSelectReward(useParam);
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
package emu.grasscutter.game.props.ItemUseAction;
|
package emu.grasscutter.game.props.ItemUseAction;
|
||||||
|
|
||||||
import emu.grasscutter.game.props.ItemUseOp;
|
import emu.grasscutter.game.props.ItemUseOp;
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
public class ItemUseAddExp extends ItemUseAction {
|
|
||||||
@Getter private int exp = 0;
|
|
||||||
|
|
||||||
|
public class ItemUseAddExp extends ItemUseInt {
|
||||||
@Override
|
@Override
|
||||||
public ItemUseOp getItemUseOp() {
|
public ItemUseOp getItemUseOp() {
|
||||||
return ItemUseOp.ITEM_USE_ADD_EXP;
|
return ItemUseOp.ITEM_USE_ADD_EXP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemUseAddExp(String[] useParam) {
|
public ItemUseAddExp(String[] useParam) {
|
||||||
try {
|
super(useParam);
|
||||||
this.exp = Integer.parseInt(useParam[0]);
|
}
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
|
public int getExp() {
|
||||||
|
return this.i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ public class ItemUseAddItem extends ItemUseInt {
|
|||||||
super(useParam);
|
super(useParam);
|
||||||
try {
|
try {
|
||||||
this.count = Integer.parseInt(useParam[1]);
|
this.count = Integer.parseInt(useParam[1]);
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException | ArrayIndexOutOfBoundsException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
package emu.grasscutter.game.props.ItemUseAction;
|
package emu.grasscutter.game.props.ItemUseAction;
|
||||||
|
|
||||||
import emu.grasscutter.game.props.ItemUseOp;
|
import emu.grasscutter.game.props.ItemUseOp;
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
public class ItemUseAddReliquaryExp extends ItemUseAction {
|
|
||||||
@Getter private int exp = 0;
|
|
||||||
|
|
||||||
|
public class ItemUseAddReliquaryExp extends ItemUseAddExp {
|
||||||
@Override
|
@Override
|
||||||
public ItemUseOp getItemUseOp() {
|
public ItemUseOp getItemUseOp() {
|
||||||
return ItemUseOp.ITEM_USE_ADD_RELIQUARY_EXP;
|
return ItemUseOp.ITEM_USE_ADD_RELIQUARY_EXP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemUseAddReliquaryExp(String[] useParam) {
|
public ItemUseAddReliquaryExp(String[] useParam) {
|
||||||
try {
|
super(useParam);
|
||||||
this.exp = Integer.parseInt(useParam[0]);
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ public class ItemUseAddServerBuff extends ItemUseInt {
|
|||||||
super(useParam);
|
super(useParam);
|
||||||
try {
|
try {
|
||||||
this.duration = Integer.parseInt(useParam[1]);
|
this.duration = Integer.parseInt(useParam[1]);
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException | ArrayIndexOutOfBoundsException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
package emu.grasscutter.game.props.ItemUseAction;
|
package emu.grasscutter.game.props.ItemUseAction;
|
||||||
|
|
||||||
import emu.grasscutter.game.props.ItemUseOp;
|
import emu.grasscutter.game.props.ItemUseOp;
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
public class ItemUseAddWeaponExp extends ItemUseAction {
|
|
||||||
@Getter private int exp = 0;
|
|
||||||
|
|
||||||
|
public class ItemUseAddWeaponExp extends ItemUseAddExp {
|
||||||
@Override
|
@Override
|
||||||
public ItemUseOp getItemUseOp() {
|
public ItemUseOp getItemUseOp() {
|
||||||
return ItemUseOp.ITEM_USE_ADD_WEAPON_EXP;
|
return ItemUseOp.ITEM_USE_ADD_WEAPON_EXP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemUseAddWeaponExp(String[] useParam) {
|
public ItemUseAddWeaponExp(String[] useParam) {
|
||||||
try {
|
super(useParam);
|
||||||
this.exp = Integer.parseInt(useParam[0]);
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,10 @@ public class ItemUseCombineItem extends ItemUseInt {
|
|||||||
super(useParam);
|
super(useParam);
|
||||||
try {
|
try {
|
||||||
this.resultId = Integer.parseInt(useParam[1]);
|
this.resultId = Integer.parseInt(useParam[1]);
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException | ArrayIndexOutOfBoundsException ignored) {}
|
||||||
try {
|
try {
|
||||||
this.resultCount = Integer.parseInt(useParam[2]);
|
this.resultCount = Integer.parseInt(useParam[2]);
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException | ArrayIndexOutOfBoundsException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,10 +19,10 @@ public class ItemUseGainAvatar extends ItemUseInt {
|
|||||||
super(useParam);
|
super(useParam);
|
||||||
try {
|
try {
|
||||||
this.level = Integer.parseInt(useParam[1]);
|
this.level = Integer.parseInt(useParam[1]);
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException | ArrayIndexOutOfBoundsException ignored) {}
|
||||||
try {
|
try {
|
||||||
this.constellation = Integer.parseInt(useParam[2]);
|
this.constellation = Integer.parseInt(useParam[2]);
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException | ArrayIndexOutOfBoundsException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -13,6 +13,7 @@ public class ItemUseGainNameCard extends ItemUseAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useItem(UseItemParams params) {
|
public boolean useItem(UseItemParams params) {
|
||||||
return false; // TODO: work out if this is actually used and how to get the namecard id
|
params.player.addNameCard(params.usedItemId);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,6 @@ public abstract class ItemUseInt extends ItemUseAction {
|
|||||||
public ItemUseInt(String[] useParam) {
|
public ItemUseInt(String[] useParam) {
|
||||||
try {
|
try {
|
||||||
this.i = Integer.parseInt(useParam[0]);
|
this.i = Integer.parseInt(useParam[0]);
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException | ArrayIndexOutOfBoundsException ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ public class UseItemParams {
|
|||||||
public int count = 1;
|
public int count = 1;
|
||||||
public int optionId = 0;
|
public int optionId = 0;
|
||||||
public boolean isEnterMpDungeonTeam = false;
|
public boolean isEnterMpDungeonTeam = false;
|
||||||
|
public int usedItemId = 0;
|
||||||
|
|
||||||
public UseItemParams(Player player, ItemUseTarget itemUseTarget, Avatar targetAvatar, int count, int optionId, boolean isEnterMpDungeonTeam) {
|
public UseItemParams(Player player, ItemUseTarget itemUseTarget, Avatar targetAvatar, int count, int optionId, boolean isEnterMpDungeonTeam) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
@ -54,7 +54,7 @@ public class QuestSystem extends BaseGameSystem {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
map.put(opcode.value().getValue(), handlerClass.newInstance());
|
map.put(opcode.value().getValue(), handlerClass.getDeclaredConstructor().newInstance());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -743,6 +743,7 @@ public class InventorySystem extends BaseGameSystem {
|
|||||||
if (itemData == null) return null;
|
if (itemData == null) return null;
|
||||||
|
|
||||||
var params = new UseItemParams(player, itemData.getUseTarget(), target, count, optionId, isEnterMpDungeonTeam);
|
var params = new UseItemParams(player, itemData.getUseTarget(), target, count, optionId, isEnterMpDungeonTeam);
|
||||||
|
params.usedItemId = item.getItemId();
|
||||||
if (useItemDirect(itemData, params)) {
|
if (useItemDirect(itemData, params)) {
|
||||||
player.getInventory().removeItem(item, count);
|
player.getInventory().removeItem(item, count);
|
||||||
var actions = itemData.getItemUseActions();
|
var actions = itemData.getItemUseActions();
|
||||||
|
@ -274,15 +274,8 @@ public class Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void showOtherEntities(Player player) {
|
public void showOtherEntities(Player player) {
|
||||||
List<GameEntity> entities = new LinkedList<>();
|
|
||||||
GameEntity currentEntity = player.getTeamManager().getCurrentAvatarEntity();
|
GameEntity currentEntity = player.getTeamManager().getCurrentAvatarEntity();
|
||||||
|
List<GameEntity> entities = this.getEntities().values().stream().filter(entity -> entity != currentEntity).toList();
|
||||||
for (GameEntity entity : this.getEntities().values()) {
|
|
||||||
if (entity == currentEntity) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
entities.add(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
player.sendPacket(new PacketSceneEntityAppearNotify(entities, VisionType.VISION_TYPE_MEET));
|
player.sendPacket(new PacketSceneEntityAppearNotify(entities, VisionType.VISION_TYPE_MEET));
|
||||||
}
|
}
|
||||||
@ -422,8 +415,8 @@ public class Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Todo
|
// Todo
|
||||||
List<GameEntity> toAdd = new LinkedList<>();
|
List<GameEntity> toAdd = new ArrayList<>();
|
||||||
List<GameEntity> toRemove = new LinkedList<>();
|
List<GameEntity> toRemove = new ArrayList<>();
|
||||||
var spawnedEntities = this.getSpawnedEntities();
|
var spawnedEntities = this.getSpawnedEntities();
|
||||||
for (SpawnDataEntry entry : visible) {
|
for (SpawnDataEntry entry : visible) {
|
||||||
// If spawn entry is in our view and hasnt been spawned/killed yet, we should spawn it
|
// If spawn entry is in our view and hasnt been spawned/killed yet, we should spawn it
|
||||||
|
@ -27,7 +27,8 @@ public class PacketOpcodesUtils {
|
|||||||
PacketOpcodes.PingRsp,
|
PacketOpcodes.PingRsp,
|
||||||
PacketOpcodes.WorldPlayerRTTNotify,
|
PacketOpcodes.WorldPlayerRTTNotify,
|
||||||
PacketOpcodes.UnionCmdNotify,
|
PacketOpcodes.UnionCmdNotify,
|
||||||
PacketOpcodes.QueryPathReq
|
PacketOpcodes.QueryPathReq,
|
||||||
|
PacketOpcodes.QueryPathRsp
|
||||||
);
|
);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -181,7 +181,7 @@ public final class PluginManager {
|
|||||||
// Add the plugin to the list of loaded plugins.
|
// Add the plugin to the list of loaded plugins.
|
||||||
this.plugins.put(identifier.name, plugin);
|
this.plugins.put(identifier.name, plugin);
|
||||||
// Create a collection for the plugin's listeners.
|
// Create a collection for the plugin's listeners.
|
||||||
this.listeners.put(plugin, new LinkedList<>());
|
this.listeners.put(plugin, new ArrayList<>());
|
||||||
|
|
||||||
// Call the plugin's onLoad method.
|
// Call the plugin's onLoad method.
|
||||||
try {
|
try {
|
||||||
@ -242,18 +242,14 @@ public final class PluginManager {
|
|||||||
* @param priority The priority to call for.
|
* @param priority The priority to call for.
|
||||||
*/
|
*/
|
||||||
private void checkAndFilter(Event event, HandlerPriority priority) {
|
private void checkAndFilter(Event event, HandlerPriority priority) {
|
||||||
// Create a collection of listeners.
|
|
||||||
List<EventHandler<? extends Event>> listeners = new LinkedList<>();
|
|
||||||
|
|
||||||
// Add all listeners from every plugin.
|
// Add all listeners from every plugin.
|
||||||
this.listeners.values().forEach(listeners::addAll);
|
this.listeners.values().stream()
|
||||||
|
.flatMap(Collection::stream)
|
||||||
listeners.stream()
|
|
||||||
// Filter the listeners by priority.
|
// Filter the listeners by priority.
|
||||||
.filter(handler -> handler.handles().isInstance(event))
|
.filter(handler -> handler.handles().isInstance(event))
|
||||||
.filter(handler -> handler.getPriority() == priority)
|
.filter(handler -> handler.getPriority() == priority)
|
||||||
// Invoke the event.
|
// Invoke the event.
|
||||||
.toList().forEach(handler -> this.invokeHandler(event, handler));
|
.forEach(handler -> this.invokeHandler(event, handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,8 +11,9 @@ import emu.grasscutter.server.game.GameServer;
|
|||||||
import emu.grasscutter.server.http.HttpServer;
|
import emu.grasscutter.server.http.HttpServer;
|
||||||
import emu.grasscutter.server.http.Router;
|
import emu.grasscutter.server.http.Router;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hooks into the {@link GameServer} class, adding convenient ways to do certain things.
|
* Hooks into the {@link GameServer} class, adding convenient ways to do certain things.
|
||||||
@ -60,8 +61,17 @@ public final class ServerHook {
|
|||||||
* Gets all online players.
|
* Gets all online players.
|
||||||
* @return Players connected to the server.
|
* @return Players connected to the server.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public List<Player> getOnlinePlayers() {
|
public List<Player> getOnlinePlayers() {
|
||||||
return new LinkedList<>(this.gameServer.getPlayers().values());
|
return new ArrayList<>(this.gameServer.getPlayers().values());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all online players.
|
||||||
|
* @return Players connected to the server.
|
||||||
|
*/
|
||||||
|
public Stream<Player> getOnlinePlayersStream() {
|
||||||
|
return this.gameServer.getPlayers().values().stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user