Compare commits
32 Commits
v0.0.5
...
v0.1.2-no-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78b3ed07e5 | ||
|
|
c25192e6fe | ||
|
|
06be6dc2e0 | ||
|
|
a7009fad05 | ||
|
|
285fcba5ab | ||
|
|
2f4956f2c7 | ||
|
|
256ac61ac0 | ||
|
|
85bce61525 | ||
|
|
cfc4d6fc1c | ||
|
|
6083f56c3b | ||
|
|
a1b8ab0f75 | ||
|
|
448c051bb3 | ||
|
|
aac01ca8c6 | ||
|
|
17c66c76c4 | ||
|
|
d28b212f63 | ||
|
|
294ef9d764 | ||
|
|
190dacd8a2 | ||
|
|
d9706290d0 | ||
|
|
adcd434c71 | ||
|
|
1245ef96d6 | ||
|
|
ab93c8b96a | ||
|
|
ab7cb30588 | ||
|
|
f7d686291f | ||
|
|
4b8e2ae8cf | ||
|
|
3450f39381 | ||
|
|
854887056e | ||
|
|
292e2de2dd | ||
|
|
3cda3a74b8 | ||
|
|
32215e5c03 | ||
|
|
fd4917ca7f | ||
|
|
c3d6c69d9d | ||
|
|
0774814912 |
21
.github/ISSUE_TEMPLATE/an-error-occurred-while-parsing-the-item.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
name: An error occurred while parsing the item
|
||||||
|
about: This is probably a bug and you can report it on GitHub.
|
||||||
|
title: "[Parse Error] - item name here"
|
||||||
|
labels: bug, parse error
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Parse Error
|
||||||
|
***Put name of item here, and in the title***
|
||||||
|
|
||||||
|
### Item Text
|
||||||
|
***Please provide the item's description***
|
||||||
|
- Can be copied with `ctrl`+`shift`+`c`
|
||||||
|
- Can also be copied from below the error message
|
||||||
|
|
||||||
|
```
|
||||||
|
Please paste it HERE
|
||||||
|
|
||||||
|
```
|
||||||
22
.github/ISSUE_TEMPLATE/not-recognized-modifier.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
name: Not Recognized Modifier
|
||||||
|
about: For "Not Recognized Modifier" errors
|
||||||
|
title: "[Not Recognized Modifier] - PUT MODIFIER HERE"
|
||||||
|
labels: bug, parse error
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Not Recognized Modifier
|
||||||
|
***Put name of item here, and in the title***
|
||||||
|
`Text of the modifier here`
|
||||||
|
|
||||||
|
### Item Text
|
||||||
|
***Please provide the item's description***
|
||||||
|
- Can be copied with `ctrl`+`shift`+`c`
|
||||||
|
- Can also be copied from below the error message
|
||||||
|
|
||||||
|
```
|
||||||
|
Please paste it HERE
|
||||||
|
|
||||||
|
```
|
||||||
18
.github/ISSUE_TEMPLATE/other-issue.md
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
name: Other Issue
|
||||||
|
about: Problem Doesn't Fit under other options
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Description
|
||||||
|
***Describe what you are experiencing (or other stuff)***
|
||||||
|
|
||||||
|
### Reproduction steps
|
||||||
|
***Steps to reproduce, if needed***
|
||||||
|
|
||||||
|
|
||||||
|
### Screenshot
|
||||||
|
***Attach screenshot if applicable***
|
||||||
24
.github/ISSUE_TEMPLATE/something-broken-in-poe2.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
name: Something Broken in PoE2
|
||||||
|
about: Use this for things that worked in PoE 1 and do not in PoE 2
|
||||||
|
title: "[PoE2] - Summary"
|
||||||
|
labels: bug
|
||||||
|
assignees: Kvan7
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the problem**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem. This is very helpful for comparing the PoE1 vs 2 problems
|
||||||
22
.github/ISSUE_TEMPLATE/unknown-item.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
name: Unknown Item
|
||||||
|
about: If this Item was introduced in this League, it will likely be supported in
|
||||||
|
the next app update.
|
||||||
|
title: "[Unknown Item] - item name here"
|
||||||
|
labels: bug, missing item
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Unknown Item
|
||||||
|
***Put name of item here, and in the title***
|
||||||
|
|
||||||
|
### Item Text
|
||||||
|
***Please provide the item's description***
|
||||||
|
- Can be copied with `ctrl`+`shift`+`c`
|
||||||
|
- Can also be copied from below the error message
|
||||||
|
|
||||||
|
```
|
||||||
|
Please paste it HERE
|
||||||
|
|
||||||
|
```
|
||||||
2
.github/workflows/main.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
|||||||
needs: renderer
|
needs: renderer
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-2019] # ubuntu-20.04, macos-14 is a missing runner
|
os: [windows-2019, ubuntu-20.04, macos-14] # ubuntu-20.04, macos-14 is a missing runner
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|||||||
10
.github/workflows/pages.yml
vendored
@@ -19,15 +19,15 @@ jobs:
|
|||||||
name: github-pages
|
name: github-pages
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v4
|
||||||
- run: npm install
|
- run: npm install
|
||||||
working-directory: ./docs
|
working-directory: ./docs
|
||||||
- run: npx vitepress build
|
- run: npx vitepress build
|
||||||
working-directory: ./docs
|
working-directory: ./docs
|
||||||
- uses: actions/configure-pages@v2
|
- uses: actions/configure-pages@v4
|
||||||
- uses: actions/upload-pages-artifact@v1
|
- uses: actions/upload-pages-artifact@v3
|
||||||
with:
|
with:
|
||||||
path: ./docs/.vitepress/dist
|
path: ./docs/.vitepress/dist
|
||||||
- id: deployment
|
- id: deployment
|
||||||
uses: actions/deploy-pages@v2
|
uses: actions/deploy-pages@v4
|
||||||
|
|||||||
3
.gitignore
vendored
@@ -1,4 +1,3 @@
|
|||||||
.DS_Store
|
|
||||||
node_modules
|
node_modules
|
||||||
*/dist/**
|
*/dist/**
|
||||||
|
|
||||||
@@ -26,3 +25,5 @@ yarn-error.log*
|
|||||||
# vitepress
|
# vitepress
|
||||||
docs/.vitepress/dist
|
docs/.vitepress/dist
|
||||||
docs/.vitepress/cache
|
docs/.vitepress/cache
|
||||||
|
|
||||||
|
*.bin
|
||||||
@@ -11,7 +11,7 @@ Note that these 2 both depend on each other, and one cannot run without the othe
|
|||||||
|
|
||||||
The most up-to-date instructions can always be derived from CI:
|
The most up-to-date instructions can always be derived from CI:
|
||||||
|
|
||||||
[.github/workflows/main.yml](https://github.com/Kvan7/Exiles-Exchange/blob/master/.github/workflows/main.yml)
|
[.github/workflows/main.yml](https://github.com/Kvan7/exiled-exchange-2/blob/master/.github/workflows/main.yml)
|
||||||
|
|
||||||
Here's what that looks like as of 2023-12-03.
|
Here's what that looks like as of 2023-12-03.
|
||||||
|
|
||||||
@@ -41,3 +41,15 @@ npm run build
|
|||||||
# install without errors
|
# install without errors
|
||||||
CSC_NAME="Certificate name in Keychain" yarn package
|
CSC_NAME="Certificate name in Keychain" yarn package
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# How to release a build
|
||||||
|
|
||||||
|
1. Commit all changes
|
||||||
|
2. Bump version in `main/package.json`
|
||||||
|
3. `npm i` in renderer & main (update `package-lock.json` with new version)
|
||||||
|
4. `npm run build` in renderer & main
|
||||||
|
5. Stage & commit bumped version
|
||||||
|
6. `git push`
|
||||||
|
7. `git tag vX.X.X`
|
||||||
|
8. `git push origin vX.X.X`
|
||||||
|
9. Open release page, create release with tag & title as text of tag & save as draft
|
||||||
|
|||||||
24
README.md
@@ -1,16 +1,28 @@
|
|||||||
#  Exile's Exchange
|
#  Exiled Exchange 2
|
||||||
|
|
||||||
## Moving from POE1
|
## Moving from POE1/Awakened PoE Trade
|
||||||
|
|
||||||
1. Download latest release from [releases](https://github.com/Kvan7/Exiles-Exchange/releases)
|
1. Download latest release from [releases](https://github.com/Kvan7/exiled-exchange-2/releases)
|
||||||
- Currently only Windows is supported
|
- Currently only Windows is supported
|
||||||
- Only available as pre-release right now
|
- Only available as pre-release right now
|
||||||
2. Run installer
|
2. Run installer
|
||||||
3. Copy `apt-data` from `%APPDATA%\awakened-poe-trade` to `%APPDATA%\Exiles-Exchange` to copy your previous settings
|
3. Run Exiled Exchange 2
|
||||||
|
4. Launch PoE2 to generate correct files
|
||||||
|
5. Quit PoE2 and EE2 after seeing the banner popup that EE2 loaded
|
||||||
|
6. Copy `apt-data` from `%APPDATA%\awakened-poe-trade` to `%APPDATA%\exiled-exchange-2` to copy your previous settings
|
||||||
- Resulting directory structure should look like this:
|
- Resulting directory structure should look like this:
|
||||||
- `%APPDATA%\Exiles-Exchange\apt-data\`
|
- `%APPDATA%\exiled-exchange-2\apt-data\`
|
||||||
- `config.json`
|
- `config.json`
|
||||||
4. Run Exiles Exchange
|
7. Edit `config.json` and change the value of "windowTitle": "Path of Exile" to instead be "Path of Exile 2", otherwise it will open only for poe1
|
||||||
|
8. Start Exiled Exchange 2 and PoE2
|
||||||
|
|
||||||
|
#### Updating from 0.0.1 -> 0.0.10
|
||||||
|
|
||||||
|
Follow same steps as tranfering from PoE1, instead of copying from `%APPDATA%\awakened-poe-trade` to `%APPDATA%\exiled-exchange-2` instead copy from `%APPDATA%\awakened-poe2-trade` or `%APPDATA%\awakened-poe2-trade2` to `%APPDATA%\exiled-exchange-2`. After copying files feel free to run the uninstaller for `awakened-poe2-trade` to remove old executables, or delete `%APPDATA%\awakened-poe2-trade` and `Local\Programs\awakened-poe2-trade`
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
https://kvan7.github.io/Exiled-Exchange-2/faq
|
||||||
|
|
||||||
## Tool showcase
|
## Tool showcase
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { defineConfig } from 'vitepress'
|
import { defineConfig } from 'vitepress'
|
||||||
|
|
||||||
const BASE = '/Exiles-Exchange/'
|
const BASE = '/Exiled-Exchange-2/'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
title: 'Exiles Exchange',
|
title: 'Exiled Exchange 2',
|
||||||
description: 'App for price-checking items in Path of Exile 2',
|
description: 'App for price-checking items in Path of Exile 2',
|
||||||
base: BASE,
|
base: BASE,
|
||||||
mpa: true,
|
mpa: true,
|
||||||
@@ -20,20 +20,15 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
// logo: 'TODO', https://github.com/vuejs/vitepress/issues/1401
|
// logo: 'TODO', https://github.com/vuejs/vitepress/issues/1401
|
||||||
appVersion: '3.25.101',
|
appVersion: '0.1.2',
|
||||||
github: {
|
github: {
|
||||||
releasesUrl: 'https://github.com/Kvan7/Exiles-Exchange/releases'
|
releasesUrl: 'https://github.com/Kvan7/Exiled-Exchange-2/releases'
|
||||||
},
|
},
|
||||||
socialLinks: [
|
socialLinks: [
|
||||||
{
|
|
||||||
text: 'Patreon',
|
|
||||||
color: '#FF424D',
|
|
||||||
link: 'https://patreon.com/awakened_poe_trade'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
text: 'GitHub',
|
text: 'GitHub',
|
||||||
color: '#181717',
|
color: '#181717',
|
||||||
link: 'https://github.com/Kvan7/Exiles-Exchange'
|
link: 'https://github.com/Kvan7/Exiled-Exchange-2'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
sidebar: [
|
sidebar: [
|
||||||
|
|||||||
15
docs/complex-query.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
title: Too Complex Query
|
||||||
|
---
|
||||||
|
|
||||||
|
This is the standard error message you will see for this error:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Either you have to log in using the built-in browser to raise the limit, reduce the query(remove total ele res), or open the query in your default browser.
|
||||||
|
|
||||||
|
Hitting "Browser" from the error message will open in the built-in browser.
|
||||||
|
|
||||||
|
To open in your default browser, hit the arrow to the right of "trade" before searching the item. Selecting "Trade" will open the trade page in the built-in browser.
|
||||||
|
|
||||||
|

|
||||||
@@ -7,21 +7,24 @@ import { useData } from 'vitepress'
|
|||||||
|
|
||||||
const { theme } = useData()
|
const { theme } = useData()
|
||||||
</script>
|
</script>
|
||||||
|
<div style="background-color: #7c2d12; color: white; padding: 10px; text-align: center; font-weight: bold; border-radius: 5px;">
|
||||||
You can download Awakened Poe Trade here. Any other mirrors are not known
|
⚠️ This is in beta for PoE2. <br/> Please be aware that there may be bugs or issues.
|
||||||
|
</div>
|
||||||
|
You can download Exiled Exchange 2 here. Any other mirrors are not known
|
||||||
to the developer, downloading from them may be unsafe.
|
to the developer, downloading from them may be unsafe.
|
||||||
|
|
||||||
| Download link | Automatic updates | Startup time |
|
| Download link | Automatic updates | Startup time |
|
||||||
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------- | ------------ |
|
| -------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------ |
|
||||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exiles-Exchange-Setup-${theme.appVersion}.exe`">Windows 10+ (installer)</a> | ✔ | Fast |
|
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-Setup-${theme.appVersion}.exe`">Windows 10+ (installer)</a> | ✔ | Fast |
|
||||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exiles-Exchange-${theme.appVersion}.exe`">Windows 10+ (portable)</a> | ❌ | Slower |
|
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-${theme.appVersion}.exe`">Windows 10+ (portable)</a> | ❌ | Slower |
|
||||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exiles-Exchange-${theme.appVersion}.AppImage`">Linux (AppImage)</a> | ✔ | n/a |
|
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-${theme.appVersion}.AppImage`">Linux (AppImage)</a> | ✔ | n/a |
|
||||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exiles-Exchange-${theme.appVersion}-universal.dmg`">macOS (dmg)</a> | ❌ | n/a |
|
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-${theme.appVersion}-universal.dmg`">macOS (dmg)</a> | ❌ | n/a |
|
||||||
|
|
||||||
Latest version is <span class="bg-gray-100 border rounded px-1">{{ theme.appVersion }}</span>
|
Latest version is <span class="bg-gray-100 border rounded px-1">{{ theme.appVersion }}</span>
|
||||||
|
|
||||||
*The app is unsigned, which means you'll have to bypass security
|
*The app is unsigned, which means you'll have to bypass security
|
||||||
warnings on Windows and [macOS](https://support.apple.com/en-us/HT202491#openanyway) to open it.{:.text-sm}
|
warnings on Windows to open it.{:.text-sm}
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -31,11 +34,11 @@ warnings on Windows and [macOS](https://support.apple.com/en-us/HT202491#openany
|
|||||||
- ✔ Windowed Fullscreen, Windowed
|
- ✔ Windowed Fullscreen, Windowed
|
||||||
- ❌ Fullscreen
|
- ❌ Fullscreen
|
||||||
- PoE language
|
- PoE language
|
||||||
- ✔ English, Russian
|
- ✔ English
|
||||||
- ❌ Portuguese, Thai, French, German, Spanish, Korean
|
- ❌ Russian, Portuguese, Thai, French, German, Spanish, Korean
|
||||||
|
|
||||||
No Administrator rights required, but\
|
No Administrator rights required, but\
|
||||||
⚠ **If you run PoE client as Admin, OS security boundaries take effect.
|
⚠ **If you run PoE client as Admin, OS security boundaries take effect.
|
||||||
In order for Exiles Exchange to have access to the PoE window, it must be started with Administrator rights.**
|
In order for Exiled Exchange 2 to have access to the PoE window, it must be started with Administrator rights.**
|
||||||
|
|
||||||
❌ **Not compatible with "GeForce Now" or any other cloud gaming service that do not forward clipboard data.**
|
❌ **Not compatible with "GeForce Now" or any other cloud gaming service that do not forward clipboard data.**
|
||||||
|
|||||||
@@ -30,15 +30,8 @@ title: FAQ
|
|||||||
|
|
||||||
- **Will my language be supported?**
|
- **Will my language be supported?**
|
||||||
|
|
||||||
No plans to support other languages. Why is there Russian language?
|
No plans to support other languages. I know Awakened PoE has Russian, but I don't have plans to add other languages since I am still fixing this to work with the new game.
|
||||||
Because:
|
|
||||||
1 - this is the native language of developer;
|
|
||||||
2 - helps to create cleaner abstractions in code and test it;
|
|
||||||
3 - has the most active community, at least according to the numbers I can measure.
|
|
||||||
|
|
||||||
09/21/2020
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- **I downloaded a zip with a bunch of files, but no .exe inside?**
|
- **I downloaded a zip with a bunch of files, but no .exe inside?**
|
||||||
|
|
||||||
|
|||||||
14
docs/invalid-json.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
title: Common issues
|
||||||
|
---
|
||||||
|
|
||||||
|
This is the standard error message you will see for this error:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This is one of two things:
|
||||||
|
|
||||||
|
- Trade site is down
|
||||||
|
- A stricter bot protection is enabled on the trade site currently
|
||||||
|
|
||||||
|
Before reporting this issue, please check if the trade site is down. If it is not those, please be incredibly detailed in the bug report, since this is commonly mis-reported when it was in fact a bot protection issue or trade site issue.
|
||||||
@@ -11,10 +11,10 @@ title: Common issues
|
|||||||
|
|
||||||
3. Are you playing with Vulkan renderer? Update GPU drivers.
|
3. Are you playing with Vulkan renderer? Update GPU drivers.
|
||||||
|
|
||||||
If Awakened works for you with DirectX11/12 renderer,
|
If EE2 works for you with DirectX11/12 renderer,
|
||||||
then problem is old Vulkan drivers for sure.
|
then problem is old Vulkan drivers for sure.
|
||||||
|
|
||||||
4. Delete `%appdata%\Exiles-Exchange`
|
4. Delete `%appdata%\exiled-exchange-2`
|
||||||
|
|
||||||
If needed, backup `apt-data` folder with your configuration inside.
|
If needed, backup `apt-data` folder with your configuration inside.
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ title: Common issues
|
|||||||
|
|
||||||
Launch them later one at a time to identify **conflict**.
|
Launch them later one at a time to identify **conflict**.
|
||||||
|
|
||||||
6. Restart Exiles Exchange.
|
6. Restart Exiled Exchange 2.
|
||||||
|
|
||||||
*(don't forget to quit first, otherwise launching second instance will do nothing).*
|
*(don't forget to quit first, otherwise launching second instance will do nothing).*
|
||||||
|
|
||||||
@@ -36,6 +36,11 @@ title: Common issues
|
|||||||
- [How to remove the stopwatch in center of screen?](https://github.com/SnosMe/awakened-poe-trade/issues/219)
|
- [How to remove the stopwatch in center of screen?](https://github.com/SnosMe/awakened-poe-trade/issues/219)
|
||||||
- [Sends a whisper when doing price-check](https://github.com/SnosMe/awakened-poe-trade/issues/178)
|
- [Sends a whisper when doing price-check](https://github.com/SnosMe/awakened-poe-trade/issues/178)
|
||||||
|
|
||||||
|
## PoE2
|
||||||
|
|
||||||
|
- 🔥[Query is too complex](/complex-query)
|
||||||
|
- 🔥[Unexpected token ..... is not valid JSON](/invalid-json)
|
||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
- 🔥[Nothing happens when I try to price check](/nothing-happens)
|
- 🔥[Nothing happens when I try to price check](/nothing-happens)
|
||||||
|
|||||||
3855
docs/package-lock.json
generated
Normal file
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
@@ -5,7 +5,7 @@ title: Quick Start
|
|||||||
#### First of all, how does it work? {:style="margin-top: 0;"}
|
#### First of all, how does it work? {:style="margin-top: 0;"}
|
||||||
|
|
||||||
When you press `Ctrl + C` Path of Exile 2 copies the item's text (under cursor, if any) to the clipboard.
|
When you press `Ctrl + C` Path of Exile 2 copies the item's text (under cursor, if any) to the clipboard.
|
||||||
All that remains is to parse text in Exiles Exchange and show to you in a fancy way.
|
All that remains is to parse text in Exiled Exchange 2 and show to you in a fancy way.
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
|
|||||||
BIN
docs/reference-images/anoint.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
docs/reference-images/axeWeapon.png
Normal file
|
After Width: | Height: | Size: 591 KiB |
BIN
docs/reference-images/bulk.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
docs/reference-images/complex.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
docs/reference-images/eleRes.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
docs/reference-images/jsonError.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
docs/reference-images/map.png
Normal file
|
After Width: | Height: | Size: 400 KiB |
BIN
docs/reference-images/tradeButton.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
@@ -8,6 +8,10 @@
|
|||||||
"name": "main",
|
"name": "main",
|
||||||
"path": "main"
|
"path": "main"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "DataStore",
|
||||||
|
"path": "./renderer/public/.DS_Store"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "docs",
|
"name": "docs",
|
||||||
"path": "docs"
|
"path": "docs"
|
||||||
@@ -25,8 +29,21 @@
|
|||||||
"dist/": true
|
"dist/": true
|
||||||
},
|
},
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
|
"editor.insertSpaces": true,
|
||||||
"conventionalCommits.scopes": [
|
"conventionalCommits.scopes": [
|
||||||
"Update to 2"
|
"Update to 2"
|
||||||
]
|
],
|
||||||
|
"cSpell.words": [
|
||||||
|
"edps",
|
||||||
|
"ilvl",
|
||||||
|
"nonunique",
|
||||||
|
"onlineleague",
|
||||||
|
"pdps",
|
||||||
|
"uniquefoil",
|
||||||
|
"WAYSTONE"
|
||||||
|
],
|
||||||
|
"files.associations": {
|
||||||
|
"*.ndjson": "jsonl"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 841 KiB After Width: | Height: | Size: 712 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 791 B After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 240 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 353 KiB After Width: | Height: | Size: 66 KiB |
BIN
main/build/icons/icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
@@ -1,6 +1,6 @@
|
|||||||
publish:
|
publish:
|
||||||
- "github"
|
- "github"
|
||||||
productName: "Exiles Exchange"
|
productName: "Exiled Exchange 2"
|
||||||
npmRebuild: false
|
npmRebuild: false
|
||||||
files:
|
files:
|
||||||
- "package.json"
|
- "package.json"
|
||||||
|
|||||||
11
main/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "Exiles-Exchange",
|
"name": "exiled-exchange-2",
|
||||||
"version": "0.0.5",
|
"version": "0.1.2-no-pseudo",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "Exiles-Exchange",
|
"name": "exiled-exchange-2",
|
||||||
"version": "0.0.5",
|
"version": "0.1.2-no-pseudo",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"electron-overlay-window": "3.3.0",
|
"electron-overlay-window": "3.3.0",
|
||||||
"uiohook-napi": "1.5.x"
|
"uiohook-napi": "1.5.x"
|
||||||
@@ -24,9 +24,6 @@
|
|||||||
"ini": "^5.0.0",
|
"ini": "^5.0.0",
|
||||||
"typescript": "5.6.x",
|
"typescript": "5.6.x",
|
||||||
"ws": "^8.16.0"
|
"ws": "^8.16.0"
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@develar/schema-utils": {
|
"node_modules/@develar/schema-utils": {
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "Exiles-Exchange",
|
"name": "exiled-exchange-2",
|
||||||
"version": "0.0.5",
|
"version": "0.1.2-no-pseudo",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "node build/script.mjs",
|
"dev": "node build/script.mjs",
|
||||||
"build": "tsc --noEmit && node build/script.mjs --prod",
|
"build": "tsc --noEmit && node build/script.mjs --prod",
|
||||||
"package": "electron-builder build"
|
"package": "electron-builder build",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"fix": "eslint src --fix"
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Alexander Drozdov"
|
"name": "Garrett Parker"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Kvan7/Exiles-Exchange.git"
|
"url": "https://github.com/Kvan7/exiled-exchange-2.git"
|
||||||
},
|
},
|
||||||
"main": "dist/main.js",
|
"main": "dist/main.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -32,8 +34,5 @@
|
|||||||
"ini": "^5.0.0",
|
"ini": "^5.0.0",
|
||||||
"typescript": "5.6.x",
|
"typescript": "5.6.x",
|
||||||
"ws": "^8.16.0"
|
"ws": "^8.16.0"
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ export class AppTray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.tray = new Tray(trayImage);
|
this.tray = new Tray(trayImage);
|
||||||
this.tray.setToolTip(`Exiles Exchange v${app.getVersion()}`);
|
this.tray.setToolTip(`Exiled Exchange 2 v${app.getVersion()}`);
|
||||||
this.rebuildMenu();
|
this.rebuildMenu();
|
||||||
|
|
||||||
server.onEventAnyClient("CLIENT->MAIN::user-action", ({ action }) => {
|
server.onEventAnyClient("CLIENT->MAIN::user-action", ({ action }) => {
|
||||||
|
|||||||
@@ -1,76 +1,82 @@
|
|||||||
import { autoUpdater } from 'electron-updater'
|
import { autoUpdater } from "electron-updater";
|
||||||
import type { ServerEvents } from './server'
|
import type { ServerEvents } from "./server";
|
||||||
import type { UpdateInfo } from '../../ipc/types'
|
import type { UpdateInfo } from "../../ipc/types";
|
||||||
|
|
||||||
export class AppUpdater {
|
export class AppUpdater {
|
||||||
private _checkedAtStartup = false
|
private _checkedAtStartup = false;
|
||||||
private _info: UpdateInfo = { state: 'initial' }
|
private _info: UpdateInfo = { state: "initial" };
|
||||||
|
|
||||||
public readonly noAutoUpdatesReason:
|
public readonly noAutoUpdatesReason: Extract<
|
||||||
Extract<UpdateInfo, { state: 'update-available' }>['noDownloadReason'] = null
|
UpdateInfo,
|
||||||
|
{ state: "update-available" }
|
||||||
|
>["noDownloadReason"] = null;
|
||||||
|
|
||||||
get info () { return this._info }
|
get info() {
|
||||||
set info (info: UpdateInfo) {
|
return this._info;
|
||||||
this._info = info
|
}
|
||||||
this.server.sendEventTo('broadcast', {
|
set info(info: UpdateInfo) {
|
||||||
name: 'MAIN->CLIENT::updater-state',
|
this._info = info;
|
||||||
payload: info
|
this.server.sendEventTo("broadcast", {
|
||||||
})
|
name: "MAIN->CLIENT::updater-state",
|
||||||
|
payload: info,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor (
|
constructor(private server: ServerEvents) {
|
||||||
private server: ServerEvents
|
setInterval(this.check, 16 * 60 * 60 * 1000);
|
||||||
) {
|
|
||||||
setInterval(this.check, 16 * 60 * 60 * 1000)
|
|
||||||
|
|
||||||
this.server.onEventAnyClient('CLIENT->MAIN::user-action', ({ action }) => {
|
this.server.onEventAnyClient("CLIENT->MAIN::user-action", ({ action }) => {
|
||||||
if (action === 'check-for-update') {
|
if (action === "check-for-update") {
|
||||||
this.check()
|
this.check();
|
||||||
} else if (action === 'update-and-restart') {
|
} else if (action === "update-and-restart") {
|
||||||
autoUpdater.quitAndInstall(false)
|
autoUpdater.quitAndInstall(false);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
// https://www.electron.build/configuration/nsis.html#portable
|
// https://www.electron.build/configuration/nsis.html#portable
|
||||||
autoUpdater.autoDownload = !process.env.PORTABLE_EXECUTABLE_DIR
|
autoUpdater.autoDownload = !process.env.PORTABLE_EXECUTABLE_DIR;
|
||||||
|
|
||||||
if (!autoUpdater.autoDownload || process.platform === 'darwin') {
|
if (!autoUpdater.autoDownload || process.platform === "darwin") {
|
||||||
this.noAutoUpdatesReason = 'not-supported'
|
this.noAutoUpdatesReason = "not-supported";
|
||||||
} else if (process.argv.includes('--no-updates')) {
|
} else if (process.argv.includes("--no-updates")) {
|
||||||
autoUpdater.autoDownload = false
|
autoUpdater.autoDownload = false;
|
||||||
this.noAutoUpdatesReason = 'disabled-by-flag'
|
this.noAutoUpdatesReason = "disabled-by-flag";
|
||||||
}
|
}
|
||||||
|
|
||||||
autoUpdater.on('checking-for-update', () => {
|
autoUpdater.on("checking-for-update", () => {
|
||||||
this.info = { state: 'checking-for-update' }
|
this.info = { state: "checking-for-update" };
|
||||||
})
|
});
|
||||||
autoUpdater.on('update-available', (info: { version: string }) => {
|
autoUpdater.on("update-available", (info: { version: string }) => {
|
||||||
this.info = { state: 'update-available', version: info.version, noDownloadReason: this.noAutoUpdatesReason }
|
this.info = {
|
||||||
})
|
state: "update-available",
|
||||||
autoUpdater.on('update-not-available', () => {
|
version: info.version,
|
||||||
this.info = { state: 'update-not-available', checkedAt: Date.now() }
|
noDownloadReason: this.noAutoUpdatesReason,
|
||||||
})
|
};
|
||||||
autoUpdater.on('error', () => {
|
});
|
||||||
this.info = { state: 'error', checkedAt: Date.now() }
|
autoUpdater.on("update-not-available", () => {
|
||||||
})
|
this.info = { state: "update-not-available", checkedAt: Date.now() };
|
||||||
autoUpdater.on('update-downloaded', (info: { version: string }) => {
|
});
|
||||||
this.info = { state: 'update-downloaded', version: info.version }
|
autoUpdater.on("error", () => {
|
||||||
})
|
this.info = { state: "error", checkedAt: Date.now() };
|
||||||
|
});
|
||||||
|
autoUpdater.on("update-downloaded", (info: { version: string }) => {
|
||||||
|
this.info = { state: "update-downloaded", version: info.version };
|
||||||
|
});
|
||||||
// on('download-progress') https://github.com/electron-userland/electron-builder/issues/2521
|
// on('download-progress') https://github.com/electron-userland/electron-builder/issues/2521
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAtStartup () {
|
checkAtStartup() {
|
||||||
if (!this._checkedAtStartup) {
|
if (!this._checkedAtStartup) {
|
||||||
this._checkedAtStartup = true
|
this._checkedAtStartup = true;
|
||||||
this.check()
|
this.check();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private check = async () => {
|
private check = async () => {
|
||||||
try {
|
try {
|
||||||
await autoUpdater.checkForUpdates()
|
await autoUpdater.checkForUpdates();
|
||||||
} catch {
|
} catch {
|
||||||
// handled by event
|
// handled by event
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
106
main/src/main.ts
@@ -1,61 +1,73 @@
|
|||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
import { app } from 'electron'
|
import { app } from "electron";
|
||||||
import { uIOhook } from 'uiohook-napi'
|
import { uIOhook } from "uiohook-napi";
|
||||||
import os from 'node:os'
|
import os from "node:os";
|
||||||
import { startServer, eventPipe, server } from './server'
|
import { startServer, eventPipe, server } from "./server";
|
||||||
import { Logger } from './RemoteLogger'
|
import { Logger } from "./RemoteLogger";
|
||||||
import { GameWindow } from './windowing/GameWindow'
|
import { GameWindow } from "./windowing/GameWindow";
|
||||||
import { OverlayWindow } from './windowing/OverlayWindow'
|
import { OverlayWindow } from "./windowing/OverlayWindow";
|
||||||
import { GameConfig } from './host-files/GameConfig'
|
import { GameConfig } from "./host-files/GameConfig";
|
||||||
import { Shortcuts } from './shortcuts/Shortcuts'
|
import { Shortcuts } from "./shortcuts/Shortcuts";
|
||||||
import { AppUpdater } from './AppUpdater'
|
import { AppUpdater } from "./AppUpdater";
|
||||||
import { AppTray } from './AppTray'
|
import { AppTray } from "./AppTray";
|
||||||
import { OverlayVisibility } from './windowing/OverlayVisibility'
|
import { OverlayVisibility } from "./windowing/OverlayVisibility";
|
||||||
import { GameLogWatcher } from './host-files/GameLogWatcher'
|
import { GameLogWatcher } from "./host-files/GameLogWatcher";
|
||||||
import { HttpProxy } from './proxy'
|
import { HttpProxy } from "./proxy";
|
||||||
|
|
||||||
if (!app.requestSingleInstanceLock()) {
|
if (!app.requestSingleInstanceLock()) {
|
||||||
app.exit()
|
app.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== "darwin") {
|
||||||
app.disableHardwareAcceleration()
|
app.disableHardwareAcceleration();
|
||||||
}
|
}
|
||||||
app.enableSandbox()
|
app.enableSandbox();
|
||||||
|
|
||||||
let tray: AppTray
|
let tray: AppTray;
|
||||||
|
|
||||||
app.on('ready', async () => {
|
app.on("ready", async () => {
|
||||||
tray = new AppTray(eventPipe)
|
tray = new AppTray(eventPipe);
|
||||||
const logger = new Logger(eventPipe)
|
const logger = new Logger(eventPipe);
|
||||||
const gameLogWatcher = new GameLogWatcher(eventPipe, logger)
|
const gameLogWatcher = new GameLogWatcher(eventPipe, logger);
|
||||||
const gameConfig = new GameConfig(eventPipe, logger)
|
const gameConfig = new GameConfig(eventPipe, logger);
|
||||||
const poeWindow = new GameWindow()
|
const poeWindow = new GameWindow();
|
||||||
const appUpdater = new AppUpdater(eventPipe)
|
const appUpdater = new AppUpdater(eventPipe);
|
||||||
const _httpProxy = new HttpProxy(server, logger)
|
const _httpProxy = new HttpProxy(server, logger);
|
||||||
|
|
||||||
setTimeout(
|
setTimeout(
|
||||||
async () => {
|
async () => {
|
||||||
const overlay = new OverlayWindow(eventPipe, logger, poeWindow)
|
const overlay = new OverlayWindow(eventPipe, logger, poeWindow);
|
||||||
new OverlayVisibility(eventPipe, overlay, gameConfig)
|
new OverlayVisibility(eventPipe, overlay, gameConfig);
|
||||||
const shortcuts = await Shortcuts.create(logger, overlay, poeWindow, gameConfig, eventPipe)
|
const shortcuts = await Shortcuts.create(
|
||||||
eventPipe.onEventAnyClient('CLIENT->MAIN::update-host-config', (cfg) => {
|
logger,
|
||||||
overlay.updateOpts(cfg.overlayKey, cfg.windowTitle)
|
overlay,
|
||||||
shortcuts.updateActions(cfg.shortcuts, cfg.stashScroll, cfg.logKeys, cfg.restoreClipboard, cfg.language)
|
poeWindow,
|
||||||
gameLogWatcher.restart(cfg.clientLog ?? '')
|
gameConfig,
|
||||||
gameConfig.readConfig(cfg.gameConfig ?? '')
|
eventPipe
|
||||||
appUpdater.checkAtStartup()
|
);
|
||||||
tray.overlayKey = cfg.overlayKey
|
eventPipe.onEventAnyClient("CLIENT->MAIN::update-host-config", (cfg) => {
|
||||||
})
|
overlay.updateOpts(cfg.overlayKey, cfg.windowTitle);
|
||||||
uIOhook.start()
|
shortcuts.updateActions(
|
||||||
const port = await startServer(appUpdater, logger)
|
cfg.shortcuts,
|
||||||
|
cfg.stashScroll,
|
||||||
|
cfg.logKeys,
|
||||||
|
cfg.restoreClipboard,
|
||||||
|
cfg.language
|
||||||
|
);
|
||||||
|
gameLogWatcher.restart(cfg.clientLog ?? "");
|
||||||
|
gameConfig.readConfig(cfg.gameConfig ?? "");
|
||||||
|
appUpdater.checkAtStartup();
|
||||||
|
tray.overlayKey = cfg.overlayKey;
|
||||||
|
});
|
||||||
|
uIOhook.start();
|
||||||
|
const port = await startServer(appUpdater, logger);
|
||||||
// TODO: move up (currently crashes)
|
// TODO: move up (currently crashes)
|
||||||
logger.write(`info ${os.type()} ${os.release} / v${app.getVersion()}`)
|
logger.write(`info ${os.type()} ${os.release} / v${app.getVersion()}`);
|
||||||
overlay.loadAppPage(port)
|
overlay.loadAppPage(port);
|
||||||
tray.serverPort = port
|
tray.serverPort = port;
|
||||||
},
|
},
|
||||||
// fixes(linux): window is black instead of transparent
|
// fixes(linux): window is black instead of transparent
|
||||||
process.platform === 'linux' ? 1000 : 0
|
process.platform === "linux" ? 1000 : 0
|
||||||
)
|
);
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -18,18 +18,10 @@ export class HttpProxy {
|
|||||||
) {
|
) {
|
||||||
server.addListener('request', (req, res) => {
|
server.addListener('request', (req, res) => {
|
||||||
if (!req.url?.startsWith('/proxy/')) return
|
if (!req.url?.startsWith('/proxy/')) return
|
||||||
|
|
||||||
const host = req.url.split('/', 3)[2]
|
const host = req.url.split('/', 3)[2]
|
||||||
logger.write(`Incoming request to proxy: ${req.url}`); // Log incoming request
|
|
||||||
|
|
||||||
const official = PROXY_HOSTS.find(entry => entry.host === host)?.official
|
const official = PROXY_HOSTS.find(entry => entry.host === host)?.official
|
||||||
if (official === undefined) {
|
if (official === undefined) return req.destroy()
|
||||||
logger.write(`Host not officially supported: ${host}`);
|
|
||||||
return req.destroy() // Log rejection on unsupported host
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log headers before modifying them
|
|
||||||
logger.write(`Incoming request headers: ${JSON.stringify(req.headers)}`);
|
|
||||||
|
|
||||||
for (const key in req.headers) {
|
for (const key in req.headers) {
|
||||||
if (key.startsWith('sec-') || key === 'host' || key === 'origin' || key === 'content-length') {
|
if (key.startsWith('sec-') || key === 'host' || key === 'origin' || key === 'content-length') {
|
||||||
@@ -37,35 +29,28 @@ export class HttpProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = req.url.slice('/proxy/'.length);
|
|
||||||
const proxyReq = net.request({
|
const proxyReq = net.request({
|
||||||
url: 'https://' + url,
|
url: 'https://' + req.url.slice('/proxy/'.length),
|
||||||
method: req.method,
|
method: req.method,
|
||||||
headers: {
|
headers: {
|
||||||
...req.headers,
|
...req.headers,
|
||||||
'user-agent': app.userAgentFallback
|
'user-agent': app.userAgentFallback
|
||||||
},
|
},
|
||||||
useSessionCookies: true
|
useSessionCookies: true,
|
||||||
|
referrerPolicy: 'no-referrer-when-downgrade'
|
||||||
})
|
})
|
||||||
|
|
||||||
proxyReq.addListener('response', (proxyRes) => {
|
proxyReq.addListener('response', (proxyRes) => {
|
||||||
const resHeaders = { ...proxyRes.headers }
|
const resHeaders = { ...proxyRes.headers }
|
||||||
// Log response status and headers
|
|
||||||
logger.write(`Proxy response status: ${proxyRes.statusCode}, status message: ${proxyRes.statusMessage}`);
|
|
||||||
logger.write(`Proxy response headers: ${JSON.stringify(resHeaders)}`);
|
|
||||||
|
|
||||||
delete resHeaders['content-encoding']
|
delete resHeaders['content-encoding']
|
||||||
res.writeHead(proxyRes.statusCode, proxyRes.statusMessage, resHeaders)
|
res.writeHead(proxyRes.statusCode, proxyRes.statusMessage, resHeaders)
|
||||||
;(proxyRes as unknown as NodeJS.ReadableStream).pipe(res)
|
;(proxyRes as unknown as NodeJS.ReadableStream).pipe(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
proxyReq.addListener('error', (err) => {
|
proxyReq.addListener('error', (err) => {
|
||||||
logger.write(`Error during proxy request: ${err.message} (${host}); is this a network error?`);
|
logger.write(`error [cors-proxy] ${err.message} (${host})`)
|
||||||
res.writeHead(502, 'Bad Gateway');
|
res.destroy(err)
|
||||||
res.end(`Proxy error: ${err.message}`);
|
|
||||||
})
|
})
|
||||||
|
|
||||||
req.pipe(proxyReq as unknown as NodeJS.WritableStream);
|
req.pipe(proxyReq as unknown as NodeJS.WritableStream)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,130 +1,178 @@
|
|||||||
import { clipboard, Clipboard } from 'electron'
|
import { clipboard, Clipboard } from "electron";
|
||||||
import type { Logger } from '../RemoteLogger'
|
import type { Logger } from "../RemoteLogger";
|
||||||
|
import { text } from "stream/consumers";
|
||||||
|
|
||||||
const POLL_DELAY = 48
|
const POLL_DELAY = 48;
|
||||||
const POLL_LIMIT = 500
|
const POLL_LIMIT = 500;
|
||||||
|
|
||||||
// PoE must read clipboard within this timeframe,
|
// PoE must read clipboard within this timeframe,
|
||||||
// after that we restore clipboard.
|
// after that we restore clipboard.
|
||||||
// If game lagged for some reason, it will read
|
// If game lagged for some reason, it will read
|
||||||
// wrong content (= restored clipboard, potentially containing password).
|
// wrong content (= restored clipboard, potentially containing password).
|
||||||
const RESTORE_AFTER = 120
|
const RESTORE_AFTER = 120;
|
||||||
|
|
||||||
export class HostClipboard {
|
export class HostClipboard {
|
||||||
private pollPromise?: Promise<string>
|
private pollPromise?: Promise<string>;
|
||||||
private elapsed = 0
|
private elapsed = 0;
|
||||||
private shouldRestore = false
|
private shouldRestore = false;
|
||||||
|
|
||||||
private isRestored = true
|
private isRestored = true;
|
||||||
|
|
||||||
get isPolling () { return this.pollPromise != null }
|
get isPolling() {
|
||||||
|
return this.pollPromise != null;
|
||||||
constructor (
|
|
||||||
private logger: Logger
|
|
||||||
) {}
|
|
||||||
|
|
||||||
updateOptions (restoreClipboard: boolean) {
|
|
||||||
this.shouldRestore = restoreClipboard
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async readItemText (): Promise<string> {
|
constructor(private logger: Logger) {}
|
||||||
this.elapsed = 0
|
|
||||||
|
updateOptions(restoreClipboard: boolean) {
|
||||||
|
this.shouldRestore = restoreClipboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
async readItemText(): Promise<string> {
|
||||||
|
this.elapsed = 0;
|
||||||
if (this.pollPromise) {
|
if (this.pollPromise) {
|
||||||
return await this.pollPromise
|
return await this.pollPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
let textBefore = clipboard.readText()
|
let textBefore = clipboard.readText();
|
||||||
if (isPoeItem(textBefore)) {
|
if (isPoeItem(textBefore)) {
|
||||||
textBefore = ''
|
textBefore = "";
|
||||||
clipboard.writeText('')
|
clipboard.writeText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pollPromise = new Promise((resolve, reject) => {
|
this.pollPromise = new Promise((resolve, reject) => {
|
||||||
const poll = () => {
|
const poll = () => {
|
||||||
const textAfter = clipboard.readText()
|
let textAfter = clipboard.readText();
|
||||||
|
|
||||||
|
if (isUncutSkillGem(textAfter)) {
|
||||||
|
// Insert item class line at start
|
||||||
|
textAfter = "Item Class: UncutSkillGem\n" + textAfter;
|
||||||
|
}
|
||||||
|
|
||||||
if (isPoeItem(textAfter)) {
|
if (isPoeItem(textAfter)) {
|
||||||
if (this.shouldRestore) {
|
if (this.shouldRestore) {
|
||||||
clipboard.writeText(textBefore)
|
clipboard.writeText(textBefore);
|
||||||
}
|
}
|
||||||
this.pollPromise = undefined
|
this.pollPromise = undefined;
|
||||||
resolve(textAfter)
|
resolve(textAfter);
|
||||||
} else {
|
} else {
|
||||||
this.elapsed += POLL_DELAY
|
this.elapsed += POLL_DELAY;
|
||||||
if (this.elapsed < POLL_LIMIT) {
|
if (this.elapsed < POLL_LIMIT) {
|
||||||
setTimeout(poll, POLL_DELAY)
|
setTimeout(poll, POLL_DELAY);
|
||||||
} else {
|
} else {
|
||||||
if (this.shouldRestore) {
|
if (this.shouldRestore) {
|
||||||
clipboard.writeText(textBefore)
|
clipboard.writeText(textBefore);
|
||||||
}
|
}
|
||||||
this.pollPromise = undefined
|
this.pollPromise = undefined;
|
||||||
|
|
||||||
if (!isPoeItem(textAfter)) {
|
if (!isPoeItem(textAfter)) {
|
||||||
this.logger.write('warn [ClipboardPoller] No item text found.')
|
this.logger.write("warn [ClipboardPoller] No item text found.");
|
||||||
}
|
}
|
||||||
reject(new Error('Reading clipboard timed out'))
|
reject(new Error("Reading clipboard timed out"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
setTimeout(poll, POLL_DELAY)
|
setTimeout(poll, POLL_DELAY);
|
||||||
})
|
});
|
||||||
|
|
||||||
return this.pollPromise
|
return this.pollPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
// when `shouldRestore` is false, this function continues
|
// when `shouldRestore` is false, this function continues
|
||||||
// to work as a throttler for callback
|
// to work as a throttler for callback
|
||||||
restoreShortly (cb: (clipboard: Clipboard) => void) {
|
restoreShortly(cb: (clipboard: Clipboard) => void) {
|
||||||
// Not only do we not overwrite the clipboard, but we don't exec callback.
|
// Not only do we not overwrite the clipboard, but we don't exec callback.
|
||||||
// This throttling helps against disconnects from "Too many actions".
|
// This throttling helps against disconnects from "Too many actions".
|
||||||
if (!this.isRestored) {
|
if (!this.isRestored) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isRestored = false
|
this.isRestored = false;
|
||||||
const saved = clipboard.readText()
|
const saved = clipboard.readText();
|
||||||
cb(clipboard)
|
cb(clipboard);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.shouldRestore) {
|
if (this.shouldRestore) {
|
||||||
clipboard.writeText(saved)
|
clipboard.writeText(saved);
|
||||||
}
|
}
|
||||||
this.isRestored = true
|
this.isRestored = true;
|
||||||
}, RESTORE_AFTER)
|
}, RESTORE_AFTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPoeItem (text: string) {
|
function isPoeItem(text: string) {
|
||||||
return LANGUAGE_DETECTOR.find(({ firstLine }) => text.startsWith(firstLine))
|
return LANGUAGE_DETECTOR.find(({ firstLine }) => text.startsWith(firstLine));
|
||||||
}
|
}
|
||||||
|
|
||||||
const LANGUAGE_DETECTOR = [{
|
function isUncutSkillGem(text: string) {
|
||||||
lang: 'en',
|
const lines = text.split("\n");
|
||||||
firstLine: 'Item Class: '
|
if (lines.length < 2) return false;
|
||||||
}, {
|
|
||||||
lang: 'ru',
|
if (
|
||||||
firstLine: 'Класс предмета: '
|
lines[0].startsWith("Rarity: Currency") &&
|
||||||
}, {
|
UNCUT_SKILL_GEM_DETECTOR.find(({ firstLine }) =>
|
||||||
lang: 'fr',
|
lines[1].startsWith(firstLine)
|
||||||
firstLine: 'Classe d\'objet: '
|
)
|
||||||
}, {
|
) {
|
||||||
lang: 'de',
|
return true;
|
||||||
firstLine: 'Gegenstandsklasse: '
|
}
|
||||||
}, {
|
|
||||||
lang: 'pt',
|
return false;
|
||||||
firstLine: 'Classe do Item: '
|
}
|
||||||
}, {
|
|
||||||
lang: 'es',
|
const UNCUT_SKILL_GEM_DETECTOR = [
|
||||||
firstLine: 'Clase de objeto: '
|
{
|
||||||
}, {
|
lang: "en",
|
||||||
lang: 'th',
|
firstLine: "Uncut Skill Gem",
|
||||||
firstLine: 'ชนิดไอเทม: '
|
},
|
||||||
}, {
|
{
|
||||||
lang: 'ko',
|
lang: "en",
|
||||||
firstLine: '아이템 종류: '
|
firstLine: "Uncut Spirit Gem",
|
||||||
}, {
|
},
|
||||||
lang: 'cmn-Hant',
|
{
|
||||||
firstLine: '物品種類: '
|
lang: "en",
|
||||||
}, {
|
firstLine: "Uncut Support Gem",
|
||||||
lang: 'cmn-Hans',
|
},
|
||||||
firstLine: '物品类别: '
|
];
|
||||||
}]
|
|
||||||
|
const LANGUAGE_DETECTOR = [
|
||||||
|
{
|
||||||
|
lang: "en",
|
||||||
|
firstLine: "Item Class: ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lang: "ru",
|
||||||
|
firstLine: "Класс предмета: ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lang: "fr",
|
||||||
|
firstLine: "Classe d'objet: ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lang: "de",
|
||||||
|
firstLine: "Gegenstandsklasse: ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lang: "pt",
|
||||||
|
firstLine: "Classe do Item: ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lang: "es",
|
||||||
|
firstLine: "Clase de objeto: ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lang: "th",
|
||||||
|
firstLine: "ชนิดไอเทม: ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lang: "ko",
|
||||||
|
firstLine: "아이템 종류: ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lang: "cmn-Hant",
|
||||||
|
firstLine: "物品種類: ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lang: "cmn-Hans",
|
||||||
|
firstLine: "物品类别: ",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|||||||
@@ -1,40 +1,53 @@
|
|||||||
import { screen, globalShortcut } from 'electron'
|
import { screen, globalShortcut } from "electron";
|
||||||
import { uIOhook, UiohookKey, UiohookWheelEvent } from 'uiohook-napi'
|
import { uIOhook, UiohookKey, UiohookWheelEvent } from "uiohook-napi";
|
||||||
import { isModKey, KeyToElectron, mergeTwoHotkeys } from '../../../ipc/KeyToCode'
|
import {
|
||||||
import { typeInChat, stashSearch } from './text-box'
|
isModKey,
|
||||||
import { WidgetAreaTracker } from '../windowing/WidgetAreaTracker'
|
KeyToElectron,
|
||||||
import { HostClipboard } from './HostClipboard'
|
mergeTwoHotkeys,
|
||||||
import { OcrWorker } from '../vision/link-main'
|
} from "../../../ipc/KeyToCode";
|
||||||
import type { ShortcutAction } from '../../../ipc/types'
|
import { typeInChat, stashSearch } from "./text-box";
|
||||||
import type { Logger } from '../RemoteLogger'
|
import { WidgetAreaTracker } from "../windowing/WidgetAreaTracker";
|
||||||
import type { OverlayWindow } from '../windowing/OverlayWindow'
|
import { HostClipboard } from "./HostClipboard";
|
||||||
import type { GameWindow } from '../windowing/GameWindow'
|
import { OcrWorker } from "../vision/link-main";
|
||||||
import type { GameConfig } from '../host-files/GameConfig'
|
import type { ShortcutAction } from "../../../ipc/types";
|
||||||
import type { ServerEvents } from '../server'
|
import type { Logger } from "../RemoteLogger";
|
||||||
|
import type { OverlayWindow } from "../windowing/OverlayWindow";
|
||||||
|
import type { GameWindow } from "../windowing/GameWindow";
|
||||||
|
import type { GameConfig } from "../host-files/GameConfig";
|
||||||
|
import type { ServerEvents } from "../server";
|
||||||
|
|
||||||
type UiohookKeyT = keyof typeof UiohookKey
|
type UiohookKeyT = keyof typeof UiohookKey;
|
||||||
const UiohookToName = Object.fromEntries(Object.entries(UiohookKey).map(([k, v]) => ([v, k])))
|
const UiohookToName = Object.fromEntries(
|
||||||
|
Object.entries(UiohookKey).map(([k, v]) => [v, k])
|
||||||
|
);
|
||||||
|
|
||||||
export class Shortcuts {
|
export class Shortcuts {
|
||||||
private actions: ShortcutAction[] = []
|
private actions: ShortcutAction[] = [];
|
||||||
private stashScroll = false
|
private stashScroll = false;
|
||||||
private logKeys = false
|
private logKeys = false;
|
||||||
private areaTracker: WidgetAreaTracker
|
private areaTracker: WidgetAreaTracker;
|
||||||
private clipboard: HostClipboard
|
private clipboard: HostClipboard;
|
||||||
|
|
||||||
static async create (
|
static async create(
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
overlay: OverlayWindow,
|
overlay: OverlayWindow,
|
||||||
poeWindow: GameWindow,
|
poeWindow: GameWindow,
|
||||||
gameConfig: GameConfig,
|
gameConfig: GameConfig,
|
||||||
server: ServerEvents
|
server: ServerEvents
|
||||||
) {
|
) {
|
||||||
const ocrWorker = await OcrWorker.create()
|
const ocrWorker = await OcrWorker.create();
|
||||||
const shortcuts = new Shortcuts(logger, overlay, poeWindow, gameConfig, server, ocrWorker)
|
const shortcuts = new Shortcuts(
|
||||||
return shortcuts
|
logger,
|
||||||
|
overlay,
|
||||||
|
poeWindow,
|
||||||
|
gameConfig,
|
||||||
|
server,
|
||||||
|
ocrWorker
|
||||||
|
);
|
||||||
|
return shortcuts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor (
|
private constructor(
|
||||||
private logger: Logger,
|
private logger: Logger,
|
||||||
private overlay: OverlayWindow,
|
private overlay: OverlayWindow,
|
||||||
private poeWindow: GameWindow,
|
private poeWindow: GameWindow,
|
||||||
@@ -42,242 +55,306 @@ export class Shortcuts {
|
|||||||
private server: ServerEvents,
|
private server: ServerEvents,
|
||||||
private ocrWorker: OcrWorker
|
private ocrWorker: OcrWorker
|
||||||
) {
|
) {
|
||||||
this.areaTracker = new WidgetAreaTracker(server, overlay)
|
this.areaTracker = new WidgetAreaTracker(server, overlay);
|
||||||
this.clipboard = new HostClipboard(logger)
|
this.clipboard = new HostClipboard(logger);
|
||||||
|
|
||||||
this.poeWindow.on('active-change', (isActive) => {
|
this.poeWindow.on("active-change", (isActive) => {
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
if (isActive === this.poeWindow.isActive) {
|
if (isActive === this.poeWindow.isActive) {
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
this.register()
|
this.register();
|
||||||
} else {
|
} else {
|
||||||
this.unregister()
|
this.unregister();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
this.server.onEventAnyClient('CLIENT->MAIN::user-action', (e) => {
|
this.server.onEventAnyClient("CLIENT->MAIN::user-action", (e) => {
|
||||||
if (e.action === 'stash-search') {
|
if (e.action === "stash-search") {
|
||||||
stashSearch(e.text, this.clipboard, this.overlay)
|
stashSearch(e.text, this.clipboard, this.overlay);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
uIOhook.on('keydown', (e) => {
|
uIOhook.on("keydown", (e) => {
|
||||||
if (!this.logKeys) return
|
if (!this.logKeys) return;
|
||||||
const pressed = eventToString(e)
|
const pressed = eventToString(e);
|
||||||
this.logger.write(`debug [Shortcuts] Keydown ${pressed}`)
|
this.logger.write(`debug [Shortcuts] Keydown ${pressed}`);
|
||||||
})
|
});
|
||||||
uIOhook.on('keyup', (e) => {
|
uIOhook.on("keyup", (e) => {
|
||||||
if (!this.logKeys) return
|
if (!this.logKeys) return;
|
||||||
this.logger.write(`debug [Shortcuts] Keyup ${UiohookToName[e.keycode] || 'not_supported_key'}`)
|
this.logger.write(
|
||||||
})
|
`debug [Shortcuts] Keyup ${
|
||||||
|
UiohookToName[e.keycode] || "not_supported_key"
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
uIOhook.on('wheel', (e) => {
|
uIOhook.on("wheel", (e) => {
|
||||||
if (!e.ctrlKey || !this.poeWindow.isActive || !this.stashScroll) return
|
if (!e.ctrlKey || !this.poeWindow.isActive || !this.stashScroll) return;
|
||||||
|
|
||||||
if (!isStashArea(e, this.poeWindow)) {
|
if (!isStashArea(e, this.poeWindow)) {
|
||||||
if (e.rotation > 0) {
|
if (e.rotation > 0) {
|
||||||
uIOhook.keyTap(UiohookKey.ArrowRight)
|
uIOhook.keyTap(UiohookKey.ArrowRight);
|
||||||
} else if (e.rotation < 0) {
|
} else if (e.rotation < 0) {
|
||||||
uIOhook.keyTap(UiohookKey.ArrowLeft)
|
uIOhook.keyTap(UiohookKey.ArrowLeft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateActions (
|
updateActions(
|
||||||
actions: ShortcutAction[],
|
actions: ShortcutAction[],
|
||||||
stashScroll: boolean,
|
stashScroll: boolean,
|
||||||
logKeys: boolean,
|
logKeys: boolean,
|
||||||
restoreClipboard: boolean,
|
restoreClipboard: boolean,
|
||||||
language: string
|
language: string
|
||||||
) {
|
) {
|
||||||
this.stashScroll = stashScroll
|
this.stashScroll = stashScroll;
|
||||||
this.logKeys = logKeys
|
this.logKeys = logKeys;
|
||||||
this.clipboard.updateOptions(restoreClipboard)
|
this.clipboard.updateOptions(restoreClipboard);
|
||||||
this.ocrWorker.updateOptions(language)
|
this.ocrWorker.updateOptions(language);
|
||||||
|
|
||||||
const copyItemShortcut = mergeTwoHotkeys('Ctrl + C', this.gameConfig.showModsKey)
|
const copyItemShortcut = mergeTwoHotkeys(
|
||||||
if (copyItemShortcut !== 'Ctrl + C') {
|
"Ctrl + C",
|
||||||
|
this.gameConfig.showModsKey
|
||||||
|
);
|
||||||
|
if (copyItemShortcut !== "Ctrl + C") {
|
||||||
actions.push({
|
actions.push({
|
||||||
shortcut: copyItemShortcut,
|
shortcut: copyItemShortcut,
|
||||||
action: { type: 'test-only' }
|
action: { type: "test-only" },
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const allShortcuts = new Set([
|
const allShortcuts = new Set([
|
||||||
'Ctrl + C', 'Ctrl + V', 'Ctrl + A',
|
"Ctrl + C",
|
||||||
'Ctrl + F',
|
"Ctrl + V",
|
||||||
'Ctrl + Enter',
|
"Ctrl + A",
|
||||||
'Home', 'Delete', 'Enter',
|
"Ctrl + F",
|
||||||
'ArrowUp', 'ArrowRight', 'ArrowLeft',
|
"Ctrl + Enter",
|
||||||
copyItemShortcut
|
"Home",
|
||||||
])
|
"Delete",
|
||||||
|
"Enter",
|
||||||
|
"ArrowUp",
|
||||||
|
"ArrowRight",
|
||||||
|
"ArrowLeft",
|
||||||
|
copyItemShortcut,
|
||||||
|
]);
|
||||||
|
|
||||||
for (const action of actions) {
|
for (const action of actions) {
|
||||||
if (allShortcuts.has(action.shortcut) && action.action.type !== 'test-only') {
|
if (
|
||||||
this.logger.write(`error [Shortcuts] Hotkey "${action.shortcut}" reserved by the game will not be registered.`)
|
allShortcuts.has(action.shortcut) &&
|
||||||
|
action.action.type !== "test-only"
|
||||||
|
) {
|
||||||
|
this.logger.write(
|
||||||
|
`error [Shortcuts] Hotkey "${action.shortcut}" reserved by the game will not be registered.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actions = actions.filter(action => !allShortcuts.has(action.shortcut))
|
actions = actions.filter((action) => !allShortcuts.has(action.shortcut));
|
||||||
|
|
||||||
const duplicates = new Set<string>()
|
const duplicates = new Set<string>();
|
||||||
for (const action of actions) {
|
for (const action of actions) {
|
||||||
if (allShortcuts.has(action.shortcut)) {
|
if (allShortcuts.has(action.shortcut)) {
|
||||||
this.logger.write(`error [Shortcuts] It is not possible to use the same hotkey "${action.shortcut}" for multiple actions.`)
|
this.logger.write(
|
||||||
duplicates.add(action.shortcut)
|
`error [Shortcuts] It is not possible to use the same hotkey "${action.shortcut}" for multiple actions.`
|
||||||
|
);
|
||||||
|
duplicates.add(action.shortcut);
|
||||||
} else {
|
} else {
|
||||||
allShortcuts.add(action.shortcut)
|
allShortcuts.add(action.shortcut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.actions = actions.filter(action =>
|
this.actions = actions.filter(
|
||||||
!duplicates.has(action.shortcut) ||
|
(action) =>
|
||||||
action.action.type === 'toggle-overlay')
|
!duplicates.has(action.shortcut) ||
|
||||||
|
action.action.type === "toggle-overlay"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private register () {
|
private register() {
|
||||||
for (const entry of this.actions) {
|
for (const entry of this.actions) {
|
||||||
const isOk = globalShortcut.register(shortcutToElectron(entry.shortcut), () => {
|
const isOk = globalShortcut.register(
|
||||||
if (this.logKeys) {
|
shortcutToElectron(entry.shortcut),
|
||||||
this.logger.write(`debug [Shortcuts] Action type: ${entry.action.type}`)
|
() => {
|
||||||
}
|
if (this.logKeys) {
|
||||||
|
this.logger.write(
|
||||||
|
`debug [Shortcuts] Action type: ${entry.action.type}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (entry.keepModKeys) {
|
if (entry.keepModKeys) {
|
||||||
const nonModKey = entry.shortcut.split(' + ').filter(key => !isModKey(key))[0]
|
const nonModKey = entry.shortcut
|
||||||
uIOhook.keyToggle(UiohookKey[nonModKey as UiohookKeyT], 'up')
|
.split(" + ")
|
||||||
} else {
|
.filter((key) => !isModKey(key))[0];
|
||||||
entry.shortcut.split(' + ').reverse().forEach(key => { uIOhook.keyToggle(UiohookKey[key as UiohookKeyT], 'up') })
|
uIOhook.keyToggle(UiohookKey[nonModKey as UiohookKeyT], "up");
|
||||||
}
|
} else {
|
||||||
|
entry.shortcut
|
||||||
|
.split(" + ")
|
||||||
|
.reverse()
|
||||||
|
.forEach((key) => {
|
||||||
|
uIOhook.keyToggle(UiohookKey[key as UiohookKeyT], "up");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (entry.action.type === 'toggle-overlay') {
|
if (entry.action.type === "toggle-overlay") {
|
||||||
this.areaTracker.removeListeners()
|
this.areaTracker.removeListeners();
|
||||||
this.overlay.toggleActiveState()
|
this.overlay.toggleActiveState();
|
||||||
} else if (entry.action.type === 'paste-in-chat') {
|
} else if (entry.action.type === "paste-in-chat") {
|
||||||
typeInChat(entry.action.text, entry.action.send, this.clipboard)
|
typeInChat(entry.action.text, entry.action.send, this.clipboard);
|
||||||
} else if (entry.action.type === 'trigger-event') {
|
} else if (entry.action.type === "trigger-event") {
|
||||||
this.server.sendEventTo('broadcast', {
|
this.server.sendEventTo("broadcast", {
|
||||||
name: 'MAIN->CLIENT::widget-action',
|
name: "MAIN->CLIENT::widget-action",
|
||||||
payload: { target: entry.action.target }
|
payload: { target: entry.action.target },
|
||||||
})
|
});
|
||||||
} else if (entry.action.type === 'stash-search') {
|
} else if (entry.action.type === "stash-search") {
|
||||||
stashSearch(entry.action.text, this.clipboard, this.overlay)
|
stashSearch(entry.action.text, this.clipboard, this.overlay);
|
||||||
} else if (entry.action.type === 'copy-item') {
|
} else if (entry.action.type === "copy-item") {
|
||||||
const { action } = entry
|
const { action } = entry;
|
||||||
|
|
||||||
const pressPosition = screen.getCursorScreenPoint()
|
const pressPosition = screen.getCursorScreenPoint();
|
||||||
|
|
||||||
this.clipboard.readItemText()
|
this.clipboard
|
||||||
.then(clipboard => {
|
.readItemText()
|
||||||
this.areaTracker.removeListeners()
|
.then((clipboard) => {
|
||||||
this.server.sendEventTo('last-active', {
|
this.areaTracker.removeListeners();
|
||||||
name: 'MAIN->CLIENT::item-text',
|
this.server.sendEventTo("last-active", {
|
||||||
payload: { target: action.target, clipboard, position: pressPosition, focusOverlay: Boolean(action.focusOverlay) }
|
name: "MAIN->CLIENT::item-text",
|
||||||
|
payload: {
|
||||||
|
target: action.target,
|
||||||
|
clipboard,
|
||||||
|
position: pressPosition,
|
||||||
|
focusOverlay: Boolean(action.focusOverlay),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (action.focusOverlay && this.overlay.wasUsedRecently) {
|
||||||
|
this.overlay.assertOverlayActive();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if (action.focusOverlay && this.overlay.wasUsedRecently) {
|
.catch(() => {});
|
||||||
this.overlay.assertOverlayActive()
|
|
||||||
}
|
|
||||||
}).catch(() => {})
|
|
||||||
|
|
||||||
pressKeysToCopyItemText(
|
pressKeysToCopyItemText(
|
||||||
(entry.keepModKeys) ? entry.shortcut.split(' + ').filter(key => isModKey(key)) : undefined,
|
entry.keepModKeys
|
||||||
this.gameConfig.showModsKey
|
? entry.shortcut.split(" + ").filter((key) => isModKey(key))
|
||||||
)
|
: undefined,
|
||||||
} else if (entry.action.type === 'ocr-text' && entry.action.target === 'heist-gems') {
|
this.gameConfig.showModsKey
|
||||||
if (process.platform !== 'win32') return
|
);
|
||||||
|
} else if (
|
||||||
|
entry.action.type === "ocr-text" &&
|
||||||
|
entry.action.target === "heist-gems"
|
||||||
|
) {
|
||||||
|
if (process.platform !== "win32") return;
|
||||||
|
|
||||||
const { action } = entry
|
const { action } = entry;
|
||||||
const pressTime = Date.now()
|
const pressTime = Date.now();
|
||||||
const imageData = this.poeWindow.screenshot()
|
const imageData = this.poeWindow.screenshot();
|
||||||
this.ocrWorker.findHeistGems({
|
this.ocrWorker
|
||||||
width: this.poeWindow.bounds.width,
|
.findHeistGems({
|
||||||
height: this.poeWindow.bounds.height,
|
width: this.poeWindow.bounds.width,
|
||||||
data: imageData
|
height: this.poeWindow.bounds.height,
|
||||||
}).then(result => {
|
data: imageData,
|
||||||
this.server.sendEventTo('last-active', {
|
})
|
||||||
name: 'MAIN->CLIENT::ocr-text',
|
.then((result) => {
|
||||||
payload: {
|
this.server.sendEventTo("last-active", {
|
||||||
target: action.target,
|
name: "MAIN->CLIENT::ocr-text",
|
||||||
pressTime,
|
payload: {
|
||||||
ocrTime: result.elapsed,
|
target: action.target,
|
||||||
paragraphs: result.recognized.map(p => p.text)
|
pressTime,
|
||||||
}
|
ocrTime: result.elapsed,
|
||||||
})
|
paragraphs: result.recognized.map((p) => p.text),
|
||||||
}).catch(() => {})
|
},
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
);
|
||||||
|
|
||||||
if (!isOk) {
|
if (!isOk) {
|
||||||
this.logger.write(`error [Shortcuts] Failed to register a shortcut "${entry.shortcut}". It is already registered by another application.`)
|
this.logger.write(
|
||||||
|
`error [Shortcuts] Failed to register a shortcut "${entry.shortcut}". It is already registered by another application.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.action.type === 'test-only') {
|
if (entry.action.type === "test-only") {
|
||||||
globalShortcut.unregister(shortcutToElectron(entry.shortcut))
|
globalShortcut.unregister(shortcutToElectron(entry.shortcut));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unregister () {
|
private unregister() {
|
||||||
globalShortcut.unregisterAll()
|
globalShortcut.unregisterAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pressKeysToCopyItemText (pressedModKeys: string[] = [], showModsKey: string) {
|
function pressKeysToCopyItemText(
|
||||||
let keys = mergeTwoHotkeys('Ctrl + C', showModsKey).split(' + ')
|
pressedModKeys: string[] = [],
|
||||||
keys = keys.filter(key => key !== 'C')
|
showModsKey: string
|
||||||
if (process.platform !== 'darwin') {
|
) {
|
||||||
|
let keys = mergeTwoHotkeys("Ctrl + C", showModsKey).split(" + ");
|
||||||
|
keys = keys.filter((key) => key !== "C");
|
||||||
|
if (process.platform !== "darwin") {
|
||||||
// On non-Mac platforms, don't toggle keys that are already being pressed.
|
// On non-Mac platforms, don't toggle keys that are already being pressed.
|
||||||
//
|
//
|
||||||
// For unknown reasons, we need to toggle pressed keys on Mac for advanced
|
// For unknown reasons, we need to toggle pressed keys on Mac for advanced
|
||||||
// mod descriptions to be copied. You can test this by setting the shortcut
|
// mod descriptions to be copied. You can test this by setting the shortcut
|
||||||
// to "Alt + any letter". They'll work with this line, but not if it's
|
// to "Alt + any letter". They'll work with this line, but not if it's
|
||||||
// commented out.
|
// commented out.
|
||||||
keys = keys.filter(key => !pressedModKeys.includes(key))
|
keys = keys.filter((key) => !pressedModKeys.includes(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
uIOhook.keyToggle(UiohookKey[key as UiohookKeyT], 'down')
|
uIOhook.keyToggle(UiohookKey[key as UiohookKeyT], "down");
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally press `C` to copy text
|
// finally press `C` to copy text
|
||||||
uIOhook.keyTap(UiohookKey.C)
|
uIOhook.keyTap(UiohookKey.C);
|
||||||
|
|
||||||
keys.reverse()
|
keys.reverse();
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
uIOhook.keyToggle(UiohookKey[key as UiohookKeyT], 'up')
|
uIOhook.keyToggle(UiohookKey[key as UiohookKeyT], "up");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isStashArea (mouse: UiohookWheelEvent, poeWindow: GameWindow): boolean {
|
function isStashArea(mouse: UiohookWheelEvent, poeWindow: GameWindow): boolean {
|
||||||
if (!poeWindow.bounds ||
|
if (
|
||||||
mouse.x > (poeWindow.bounds.x + poeWindow.uiSidebarWidth)) return false
|
!poeWindow.bounds ||
|
||||||
|
mouse.x > poeWindow.bounds.x + poeWindow.uiSidebarWidth
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
|
||||||
return (mouse.y > (poeWindow.bounds.y + poeWindow.bounds.height * 154 / 1600) &&
|
return (
|
||||||
mouse.y < (poeWindow.bounds.y + poeWindow.bounds.height * 1192 / 1600))
|
mouse.y > poeWindow.bounds.y + (poeWindow.bounds.height * 154) / 1600 &&
|
||||||
|
mouse.y < poeWindow.bounds.y + (poeWindow.bounds.height * 1192) / 1600
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function eventToString (e: { keycode: number, ctrlKey: boolean, altKey: boolean, shiftKey: boolean }) {
|
function eventToString(e: {
|
||||||
const { ctrlKey, shiftKey, altKey } = e
|
keycode: number;
|
||||||
|
ctrlKey: boolean;
|
||||||
|
altKey: boolean;
|
||||||
|
shiftKey: boolean;
|
||||||
|
}) {
|
||||||
|
const { ctrlKey, shiftKey, altKey } = e;
|
||||||
|
|
||||||
let code = UiohookToName[e.keycode]
|
let code = UiohookToName[e.keycode];
|
||||||
if (!code) return 'not_supported_key'
|
if (!code) return "not_supported_key";
|
||||||
|
|
||||||
if (code === 'Shift' || code === 'Alt' || code === 'Ctrl') return code
|
if (code === "Shift" || code === "Alt" || code === "Ctrl") return code;
|
||||||
|
|
||||||
if (ctrlKey && shiftKey && altKey) code = `Ctrl + Shift + Alt + ${code}`
|
if (ctrlKey && shiftKey && altKey) code = `Ctrl + Shift + Alt + ${code}`;
|
||||||
else if (shiftKey && altKey) code = `Shift + Alt + ${code}`
|
else if (shiftKey && altKey) code = `Shift + Alt + ${code}`;
|
||||||
else if (ctrlKey && shiftKey) code = `Ctrl + Shift + ${code}`
|
else if (ctrlKey && shiftKey) code = `Ctrl + Shift + ${code}`;
|
||||||
else if (ctrlKey && altKey) code = `Ctrl + Alt + ${code}`
|
else if (ctrlKey && altKey) code = `Ctrl + Alt + ${code}`;
|
||||||
else if (altKey) code = `Alt + ${code}`
|
else if (altKey) code = `Alt + ${code}`;
|
||||||
else if (ctrlKey) code = `Ctrl + ${code}`
|
else if (ctrlKey) code = `Ctrl + ${code}`;
|
||||||
else if (shiftKey) code = `Shift + ${code}`
|
else if (shiftKey) code = `Shift + ${code}`;
|
||||||
|
|
||||||
return code
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
function shortcutToElectron (shortcut: string) {
|
function shortcutToElectron(shortcut: string) {
|
||||||
return shortcut
|
return shortcut
|
||||||
.split(' + ')
|
.split(" + ")
|
||||||
.map(k => KeyToElectron[k as keyof typeof KeyToElectron])
|
.map((k) => KeyToElectron[k as keyof typeof KeyToElectron])
|
||||||
.join('+')
|
.join("+");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ export class OverlayWindow {
|
|||||||
// ----------------------
|
// ----------------------
|
||||||
"Path of Exile 2 is running with administrator rights.\n" +
|
"Path of Exile 2 is running with administrator rights.\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"You need to restart Exiles Exchange with administrator rights."
|
"You need to restart Exiled Exchange 2 with administrator rights."
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.server.sendEventTo("broadcast", {
|
this.server.sendEventTo("broadcast", {
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
env: {
|
env: {
|
||||||
node: true
|
node: true,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
'@typescript-eslint',
|
"@typescript-eslint",
|
||||||
// 'only-warn'
|
// 'only-warn'
|
||||||
],
|
],
|
||||||
extends: [
|
extends: ["plugin:vue/base", "standard-with-typescript", "prettier"],
|
||||||
'plugin:vue/base',
|
|
||||||
'standard-with-typescript',
|
|
||||||
],
|
|
||||||
rules: {
|
rules: {
|
||||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||||
'quote-props': ['error', 'consistent-as-needed'],
|
"quote-props": ["error", "consistent-as-needed"],
|
||||||
'no-labels': ['error', { allowLoop: true }],
|
"no-labels": ["error", { allowLoop: true }],
|
||||||
'multiline-ternary': 'off',
|
"multiline-ternary": "off",
|
||||||
'no-unused-vars': 'off',
|
"no-unused-vars": "off",
|
||||||
'no-undef': 'off',
|
"no-undef": "off",
|
||||||
'@typescript-eslint/no-unused-vars': ['error'],
|
"@typescript-eslint/no-unused-vars": ["error"],
|
||||||
'@typescript-eslint/strict-boolean-expressions': 'off',
|
"@typescript-eslint/strict-boolean-expressions": "off",
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
'@typescript-eslint/restrict-template-expressions': 'off',
|
"@typescript-eslint/restrict-template-expressions": "off",
|
||||||
'@typescript-eslint/prefer-nullish-coalescing': 'off',
|
"@typescript-eslint/prefer-nullish-coalescing": "off",
|
||||||
'@typescript-eslint/prefer-optional-chain': 'off',
|
"@typescript-eslint/prefer-optional-chain": "off",
|
||||||
'@typescript-eslint/prefer-readonly': 'off',
|
"@typescript-eslint/prefer-readonly": "off",
|
||||||
'@typescript-eslint/no-floating-promises': 'off',
|
"@typescript-eslint/no-floating-promises": "off",
|
||||||
'@typescript-eslint/no-misused-promises': 'off',
|
"@typescript-eslint/no-misused-promises": "off",
|
||||||
'@typescript-eslint/prefer-reduce-type-parameter': 'off',
|
"@typescript-eslint/prefer-reduce-type-parameter": "off",
|
||||||
'@typescript-eslint/no-invalid-void-type': 'off',
|
"@typescript-eslint/no-invalid-void-type": "off",
|
||||||
'@typescript-eslint/consistent-indexed-object-style': 'off',
|
"@typescript-eslint/consistent-indexed-object-style": "off",
|
||||||
'import/first': 'off',
|
"import/first": "off",
|
||||||
'import/no-duplicates': 'off',
|
"import/no-duplicates": "off",
|
||||||
'func-call-spacing': 'off',
|
"func-call-spacing": "off",
|
||||||
// TODO: refactor IPC and enable
|
// TODO: refactor IPC and enable
|
||||||
'@typescript-eslint/consistent-type-assertions': 'off',
|
"@typescript-eslint/consistent-type-assertions": "off",
|
||||||
},
|
},
|
||||||
overrides: [{
|
overrides: [
|
||||||
files: ['src/main/**/*'],
|
{
|
||||||
env: {
|
files: ["src/main/**/*"],
|
||||||
node: true
|
env: {
|
||||||
}
|
node: true,
|
||||||
}, {
|
},
|
||||||
files: ['*.ts'],
|
},
|
||||||
parserOptions: {
|
{
|
||||||
project: './tsconfig.json'
|
files: ["*.ts"],
|
||||||
}
|
parserOptions: {
|
||||||
}],
|
project: "./tsconfig.json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
parser: '@typescript-eslint/parser',
|
parser: "@typescript-eslint/parser",
|
||||||
extraFileExtensions: ['.vue']
|
extraFileExtensions: [".vue"],
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|||||||
6
renderer/.prettierignore
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Ignore artifacts:
|
||||||
|
build
|
||||||
|
coverage
|
||||||
|
dist
|
||||||
|
node_modules
|
||||||
|
public
|
||||||
1
renderer/.prettierrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||||
|
<meta name="color-scheme" content="dark" />
|
||||||
|
<link rel="icon" href="/icon.ico" />
|
||||||
|
<title>Exiled Exchange 2</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
<head>
|
<body>
|
||||||
<meta charset="utf-8">
|
<div id="app"></div>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<script type="module" src="/src/main.ts"></script>
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
</body>
|
||||||
<meta name="color-scheme" content="dark">
|
</html>
|
||||||
<link rel="icon" href="/icon.ico">
|
|
||||||
<title>Exiles Exchange</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
|
|||||||
731
renderer/package-lock.json
generated
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "Exiles-Exchange",
|
"name": "exiled-exchange-2",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
"lint": "eslint --ext .ts,.vue src",
|
"lint": "eslint --ext .ts,.vue src",
|
||||||
"lint-fix": "eslint --ext .ts,.vue src --fix",
|
"lint-fix": "eslint --ext .ts,.vue src --fix",
|
||||||
"build": "vue-tsc --noEmit && vite build",
|
"build": "vue-tsc --noEmit && vite build",
|
||||||
"make-index-files": "node src/assets/make-index-files.mjs"
|
"make-index-files": "node src/assets/make-index-files.mjs",
|
||||||
|
"test": "vitest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "6.x.x",
|
"@fortawesome/fontawesome-free": "6.x.x",
|
||||||
@@ -35,9 +36,14 @@
|
|||||||
"@types/object-hash": "^3.0.0",
|
"@types/object-hash": "^3.0.0",
|
||||||
"@vitejs/plugin-vue": "^4.0.0",
|
"@vitejs/plugin-vue": "^4.0.0",
|
||||||
"autoprefixer": "^10.0.2",
|
"autoprefixer": "^10.0.2",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"postcss": "^8.2.14",
|
"postcss": "^8.2.14",
|
||||||
|
"prettier": "3.4.2",
|
||||||
"typescript": "5.6.x",
|
"typescript": "5.6.x",
|
||||||
"vite": "^5.0.0",
|
"vite": "^5.0.0",
|
||||||
|
"vite-tsconfig-paths": "^5.1.4",
|
||||||
|
"vitest": "^2.1.8",
|
||||||
|
"vitest-mock-extended": "^2.0.2",
|
||||||
"vue-tsc": "^2.0.0"
|
"vue-tsc": "^2.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
|||||||
169
renderer/public/.DS_Store/.gitignore
vendored
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
|
__pycache__
|
||||||
|
|
||||||
|
vendor/json-api/*.json
|
||||||
|
vendor/json-api/en/*.json
|
||||||
|
vendor/json-api/ru/*.json
|
||||||
|
vendor/json-api/ko/*.json
|
||||||
|
vendor/json-api/cmn-Hant/*.json
|
||||||
|
vendor/client/tables/*.json
|
||||||
|
vendor/client/descriptions/*
|
||||||
|
!vendor/client/descriptions/.gitkeep
|
||||||
|
|
||||||
|
vendor/client/tables/*
|
||||||
|
!vendor/client/tables/index.ts
|
||||||
|
!vendor/client/tables/ArmourTypesOverride.json
|
||||||
|
!vendor/client/tables/en/.gitkeep
|
||||||
|
!vendor/client/tables/ru/.gitkeep
|
||||||
|
!vendor/client/tables/ko/.gitkeep
|
||||||
|
!vendor/client/tables/cmn-Hant/.gitkeep
|
||||||
|
|
||||||
|
!vendor/client/tables/en/ArmourTypesOverride.json
|
||||||
|
!vendor/client/tables/ru/ArmourTypesOverride.json
|
||||||
|
!vendor/client/tables/ko/ArmourTypesOverride.json
|
||||||
|
!vendor/client/tables/cmn-Hant/ArmourTypesOverride.json
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
!vendor/json-api/.gitkeep
|
||||||
|
!vendor/json-api/en/.gitkeep
|
||||||
|
!vendor/json-api/ru/.gitkeep
|
||||||
|
!vendor/json-api/ko/.gitkeep
|
||||||
|
!vendor/json-api/cmn-Hant/.gitkeep
|
||||||
|
|
||||||
|
|
||||||
|
EXPORT/tables/English/*.json
|
||||||
|
EXPORT/tables/Korean/*.json
|
||||||
|
EXPORT/tables/Russian/*.json
|
||||||
|
EXPORT/tables/Traditional Chinese/*.json
|
||||||
|
|
||||||
127
renderer/public/.DS_Store/EXPORT/config.json
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
{
|
||||||
|
"steam": "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Path of Exile 2",
|
||||||
|
"translations": [
|
||||||
|
"English",
|
||||||
|
"Russian"
|
||||||
|
],
|
||||||
|
"tables": [
|
||||||
|
{
|
||||||
|
"name": "BaseItemTypes",
|
||||||
|
"columns": [
|
||||||
|
"Id",
|
||||||
|
"Name",
|
||||||
|
"IsCorrupted",
|
||||||
|
"Width",
|
||||||
|
"Height",
|
||||||
|
"DropLevel",
|
||||||
|
"ItemVisualIdentity",
|
||||||
|
"Implicit_ModsKeys",
|
||||||
|
"ItemClassesKey",
|
||||||
|
"SiteVisibility",
|
||||||
|
"TagsKeys",
|
||||||
|
"TradeMarketCategory"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ItemClasses",
|
||||||
|
"columns": [
|
||||||
|
"Id",
|
||||||
|
"Name",
|
||||||
|
"ItemClassCategory",
|
||||||
|
"TradeMarketCategory"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "WeaponTypes",
|
||||||
|
"columns": [
|
||||||
|
"BaseItemTypesKey",
|
||||||
|
"DamageMin",
|
||||||
|
"DamageMax"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ItemClassCategories",
|
||||||
|
"columns": [
|
||||||
|
"Id",
|
||||||
|
"Text"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SkillGems",
|
||||||
|
"columns": [
|
||||||
|
"BaseItemTypesKey",
|
||||||
|
"IsVaalVariant",
|
||||||
|
"IsSupport"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SkillGemInfo",
|
||||||
|
"columns": [
|
||||||
|
"Id",
|
||||||
|
"Description",
|
||||||
|
"SkillGemsKey"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mods",
|
||||||
|
"columns": [
|
||||||
|
"Id",
|
||||||
|
"Domain",
|
||||||
|
"Name",
|
||||||
|
"StatsKey1",
|
||||||
|
"StatsKey2",
|
||||||
|
"StatsKey3",
|
||||||
|
"StatsKey4"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tags",
|
||||||
|
"columns": [
|
||||||
|
"Id",
|
||||||
|
"DisplayString"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "UniqueStashLayout",
|
||||||
|
"columns": [
|
||||||
|
"WordsKey",
|
||||||
|
"ItemVisualIdentityKey",
|
||||||
|
"UniqueStashTypesKey",
|
||||||
|
"RenamedVersion",
|
||||||
|
"ShowIfEmptyChallengeLeague"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Words",
|
||||||
|
"columns": [
|
||||||
|
"Wordlist",
|
||||||
|
"Text",
|
||||||
|
"Text2",
|
||||||
|
"SpawnWeight_Tags",
|
||||||
|
"SpawnWeight_Values"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ItemVisualIdentity",
|
||||||
|
"columns": [
|
||||||
|
"Id",
|
||||||
|
"DDSFile",
|
||||||
|
"AOFile"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Stats",
|
||||||
|
"columns": [
|
||||||
|
"Id",
|
||||||
|
"IsLocal",
|
||||||
|
"IsWeaponLocal",
|
||||||
|
"Semantics",
|
||||||
|
"Text",
|
||||||
|
"IsVirtual",
|
||||||
|
"HASH32",
|
||||||
|
"BelongsActiveSkillsKey",
|
||||||
|
"IsScalable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
51752
renderer/public/.DS_Store/EXPORT/tables/Russian/BaseItemTypes.json
Normal file
758
renderer/public/.DS_Store/EXPORT/tables/Russian/ItemClasses.json
Normal file
@@ -0,0 +1,758 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"_index": 0,
|
||||||
|
"Id": "LifeFlask",
|
||||||
|
"Name": "Флаконы жизни",
|
||||||
|
"TradeMarketCategory": 28,
|
||||||
|
"ItemClassCategory": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 1,
|
||||||
|
"Id": "ManaFlask",
|
||||||
|
"Name": "Флаконы маны",
|
||||||
|
"TradeMarketCategory": 29,
|
||||||
|
"ItemClassCategory": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 2,
|
||||||
|
"Id": "DONOTUSE5",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 3,
|
||||||
|
"Id": "Currency",
|
||||||
|
"Name": "Вещи на обмен",
|
||||||
|
"TradeMarketCategory": 39,
|
||||||
|
"ItemClassCategory": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 4,
|
||||||
|
"Id": "Amulet",
|
||||||
|
"Name": "Амулеты",
|
||||||
|
"TradeMarketCategory": 21,
|
||||||
|
"ItemClassCategory": 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 5,
|
||||||
|
"Id": "Ring",
|
||||||
|
"Name": "Кольца",
|
||||||
|
"TradeMarketCategory": 22,
|
||||||
|
"ItemClassCategory": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 6,
|
||||||
|
"Id": "Claw",
|
||||||
|
"Name": "Когти",
|
||||||
|
"TradeMarketCategory": 4,
|
||||||
|
"ItemClassCategory": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 7,
|
||||||
|
"Id": "Dagger",
|
||||||
|
"Name": "Кинжалы",
|
||||||
|
"TradeMarketCategory": 5,
|
||||||
|
"ItemClassCategory": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 8,
|
||||||
|
"Id": "Wand",
|
||||||
|
"Name": "Жезлы",
|
||||||
|
"TradeMarketCategory": 6,
|
||||||
|
"ItemClassCategory": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 9,
|
||||||
|
"Id": "One Hand Sword",
|
||||||
|
"Name": "Одноручные мечи",
|
||||||
|
"TradeMarketCategory": 7,
|
||||||
|
"ItemClassCategory": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 10,
|
||||||
|
"Id": "DONOTUSE6",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 11,
|
||||||
|
"Id": "One Hand Axe",
|
||||||
|
"Name": "Одноручные топоры",
|
||||||
|
"TradeMarketCategory": 9,
|
||||||
|
"ItemClassCategory": 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 12,
|
||||||
|
"Id": "One Hand Mace",
|
||||||
|
"Name": "Одноручные булавы",
|
||||||
|
"TradeMarketCategory": 10,
|
||||||
|
"ItemClassCategory": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 13,
|
||||||
|
"Id": "Bow",
|
||||||
|
"Name": "Луки",
|
||||||
|
"TradeMarketCategory": 13,
|
||||||
|
"ItemClassCategory": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 14,
|
||||||
|
"Id": "Staff",
|
||||||
|
"Name": "Посохи",
|
||||||
|
"TradeMarketCategory": 14,
|
||||||
|
"ItemClassCategory": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 15,
|
||||||
|
"Id": "Two Hand Sword",
|
||||||
|
"Name": "Двуручные мечи",
|
||||||
|
"TradeMarketCategory": 15,
|
||||||
|
"ItemClassCategory": 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 16,
|
||||||
|
"Id": "Two Hand Axe",
|
||||||
|
"Name": "Двуручные топоры",
|
||||||
|
"TradeMarketCategory": 16,
|
||||||
|
"ItemClassCategory": 14
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 17,
|
||||||
|
"Id": "Two Hand Mace",
|
||||||
|
"Name": "Двуручные булавы",
|
||||||
|
"TradeMarketCategory": 17,
|
||||||
|
"ItemClassCategory": 15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 18,
|
||||||
|
"Id": "Active Skill Gem",
|
||||||
|
"Name": "Камни умений",
|
||||||
|
"TradeMarketCategory": 26,
|
||||||
|
"ItemClassCategory": 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 19,
|
||||||
|
"Id": "Support Skill Gem",
|
||||||
|
"Name": "Камни поддержки",
|
||||||
|
"TradeMarketCategory": 27,
|
||||||
|
"ItemClassCategory": 17
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 20,
|
||||||
|
"Id": "Quiver",
|
||||||
|
"Name": "Колчаны",
|
||||||
|
"TradeMarketCategory": 19,
|
||||||
|
"ItemClassCategory": 18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 21,
|
||||||
|
"Id": "Belt",
|
||||||
|
"Name": "Пояса",
|
||||||
|
"TradeMarketCategory": 23,
|
||||||
|
"ItemClassCategory": 19
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 22,
|
||||||
|
"Id": "Gloves",
|
||||||
|
"Name": "Перчатки",
|
||||||
|
"TradeMarketCategory": 0,
|
||||||
|
"ItemClassCategory": 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 23,
|
||||||
|
"Id": "Boots",
|
||||||
|
"Name": "Обувь",
|
||||||
|
"TradeMarketCategory": 1,
|
||||||
|
"ItemClassCategory": 21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 24,
|
||||||
|
"Id": "Body Armour",
|
||||||
|
"Name": "Доспехи",
|
||||||
|
"TradeMarketCategory": 2,
|
||||||
|
"ItemClassCategory": 22
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 25,
|
||||||
|
"Id": "Helmet",
|
||||||
|
"Name": "Шлемы",
|
||||||
|
"TradeMarketCategory": 3,
|
||||||
|
"ItemClassCategory": 23
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 26,
|
||||||
|
"Id": "Shield",
|
||||||
|
"Name": "Щиты",
|
||||||
|
"TradeMarketCategory": 20,
|
||||||
|
"ItemClassCategory": 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 27,
|
||||||
|
"Id": "SmallRelic",
|
||||||
|
"Name": "Малые реликвии",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 28,
|
||||||
|
"Id": "MediumRelic",
|
||||||
|
"Name": "Средние реликвии",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 29,
|
||||||
|
"Id": "LargeRelic",
|
||||||
|
"Name": "Большие реликвии",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 30,
|
||||||
|
"Id": "StackableCurrency",
|
||||||
|
"Name": "Валюта",
|
||||||
|
"TradeMarketCategory": 39,
|
||||||
|
"ItemClassCategory": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 31,
|
||||||
|
"Id": "QuestItem",
|
||||||
|
"Name": "Вещи для заданий",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 32,
|
||||||
|
"Id": "Sceptre",
|
||||||
|
"Name": "Скипетры",
|
||||||
|
"TradeMarketCategory": 11,
|
||||||
|
"ItemClassCategory": 61
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 33,
|
||||||
|
"Id": "UtilityFlask",
|
||||||
|
"Name": "Обереги",
|
||||||
|
"TradeMarketCategory": 31,
|
||||||
|
"ItemClassCategory": 69
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 34,
|
||||||
|
"Id": "DONOTUSE7",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 35,
|
||||||
|
"Id": "Map",
|
||||||
|
"Name": "Путевые камни",
|
||||||
|
"TradeMarketCategory": 34,
|
||||||
|
"ItemClassCategory": 26
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 36,
|
||||||
|
"Id": "Unarmed",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 66
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 37,
|
||||||
|
"Id": "FishingRod",
|
||||||
|
"Name": "Удочки",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 27
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 38,
|
||||||
|
"Id": "MapFragment",
|
||||||
|
"Name": "Обрывки карт",
|
||||||
|
"TradeMarketCategory": 37,
|
||||||
|
"ItemClassCategory": 28
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 39,
|
||||||
|
"Id": "HideoutDoodad",
|
||||||
|
"Name": "Предметы убежища",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 40,
|
||||||
|
"Id": "Microtransaction",
|
||||||
|
"Name": "Микротранзакции",
|
||||||
|
"TradeMarketCategory": 53,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 41,
|
||||||
|
"Id": "Jewel",
|
||||||
|
"Name": "Самоцветы",
|
||||||
|
"TradeMarketCategory": 35,
|
||||||
|
"ItemClassCategory": 29
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 42,
|
||||||
|
"Id": "DivinationCard",
|
||||||
|
"Name": "Гадальные карты",
|
||||||
|
"TradeMarketCategory": 40,
|
||||||
|
"ItemClassCategory": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 43,
|
||||||
|
"Id": "DONOTUSE8",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 44,
|
||||||
|
"Id": "DONOTUSE9",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 45,
|
||||||
|
"Id": "DONOTUSE10",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 46,
|
||||||
|
"Id": "MiscMapItem",
|
||||||
|
"Name": "Прочие предметы карт",
|
||||||
|
"TradeMarketCategory": 38,
|
||||||
|
"ItemClassCategory": 33
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 47,
|
||||||
|
"Id": "Leaguestone",
|
||||||
|
"Name": "Камни лиги",
|
||||||
|
"TradeMarketCategory": 33,
|
||||||
|
"ItemClassCategory": 34
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 48,
|
||||||
|
"Id": "PantheonSoul",
|
||||||
|
"Name": "Души Пантеона",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 49,
|
||||||
|
"Id": "UniqueFragment",
|
||||||
|
"Name": "Фрагменты",
|
||||||
|
"TradeMarketCategory": 41,
|
||||||
|
"ItemClassCategory": 36
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 50,
|
||||||
|
"Id": "AbyssJewel",
|
||||||
|
"Name": "Самоцветы Бездны",
|
||||||
|
"TradeMarketCategory": 36,
|
||||||
|
"ItemClassCategory": 37
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 51,
|
||||||
|
"Id": "IncursionItem",
|
||||||
|
"Name": "Предметы Вмешательства",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 38
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 52,
|
||||||
|
"Id": "DelveSocketableCurrency",
|
||||||
|
"Name": "Валюта Спуска",
|
||||||
|
"TradeMarketCategory": 43,
|
||||||
|
"ItemClassCategory": 39
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 53,
|
||||||
|
"Id": "Incubator",
|
||||||
|
"Name": "Инкубаторы",
|
||||||
|
"TradeMarketCategory": 45,
|
||||||
|
"ItemClassCategory": 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 54,
|
||||||
|
"Id": "UniqueShard",
|
||||||
|
"Name": "Осколки",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 55,
|
||||||
|
"Id": "UniqueShardBase",
|
||||||
|
"Name": "Стержни осколков",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 56,
|
||||||
|
"Id": "DONOTUSE11",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 57,
|
||||||
|
"Id": "Warstaff",
|
||||||
|
"Name": "Боевые посохи",
|
||||||
|
"TradeMarketCategory": 18,
|
||||||
|
"ItemClassCategory": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 58,
|
||||||
|
"Id": "DelveStackableSocketableCurrency",
|
||||||
|
"Name": "Валюта Спуска",
|
||||||
|
"TradeMarketCategory": 43,
|
||||||
|
"ItemClassCategory": 39
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 59,
|
||||||
|
"Id": "AtlasUpgradeItem",
|
||||||
|
"Name": "Предметы улучшения Атласа",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 41
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 60,
|
||||||
|
"Id": "DONOTUSE4",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 61,
|
||||||
|
"Id": "HiddenItem",
|
||||||
|
"Name": "Сокрытые предметы",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 62,
|
||||||
|
"Id": "DONOTUSE1",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 63,
|
||||||
|
"Id": "DONOTUSE2",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 64,
|
||||||
|
"Id": "DONOTUSE3",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 65,
|
||||||
|
"Id": "HeistContract",
|
||||||
|
"Name": "Контракты",
|
||||||
|
"TradeMarketCategory": 48,
|
||||||
|
"ItemClassCategory": 42
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 66,
|
||||||
|
"Id": "HeistEquipmentWeapon",
|
||||||
|
"Name": "Разбойничьи принадлежности",
|
||||||
|
"TradeMarketCategory": 48,
|
||||||
|
"ItemClassCategory": 43
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 67,
|
||||||
|
"Id": "HeistEquipmentTool",
|
||||||
|
"Name": "Разбойничий инструмент",
|
||||||
|
"TradeMarketCategory": 48,
|
||||||
|
"ItemClassCategory": 44
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 68,
|
||||||
|
"Id": "HeistEquipmentUtility",
|
||||||
|
"Name": "Разбойничьи накидки",
|
||||||
|
"TradeMarketCategory": 48,
|
||||||
|
"ItemClassCategory": 45
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 69,
|
||||||
|
"Id": "HeistEquipmentReward",
|
||||||
|
"Name": "Разбойничьи броши",
|
||||||
|
"TradeMarketCategory": 48,
|
||||||
|
"ItemClassCategory": 46
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 70,
|
||||||
|
"Id": "HeistBlueprint",
|
||||||
|
"Name": "Чертежи",
|
||||||
|
"TradeMarketCategory": 48,
|
||||||
|
"ItemClassCategory": 47
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 71,
|
||||||
|
"Id": "Trinket",
|
||||||
|
"Name": "Украшения",
|
||||||
|
"TradeMarketCategory": 25,
|
||||||
|
"ItemClassCategory": 48
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 72,
|
||||||
|
"Id": "HeistObjective",
|
||||||
|
"Name": "Предметы кражи",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 49
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 73,
|
||||||
|
"Id": "ExpeditionLogbook",
|
||||||
|
"Name": "Журналы экспедиции",
|
||||||
|
"TradeMarketCategory": 49,
|
||||||
|
"ItemClassCategory": 50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 74,
|
||||||
|
"Id": "IncubatorStackable",
|
||||||
|
"Name": "Инкубаторы",
|
||||||
|
"TradeMarketCategory": 45,
|
||||||
|
"ItemClassCategory": 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 75,
|
||||||
|
"Id": "ArchnemesisMod",
|
||||||
|
"Name": "Свойства Возмездия",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 76,
|
||||||
|
"Id": "Meta Skill Gem",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 64
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 77,
|
||||||
|
"Id": "Spear",
|
||||||
|
"Name": "Копья",
|
||||||
|
"TradeMarketCategory": 55,
|
||||||
|
"ItemClassCategory": 57
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 78,
|
||||||
|
"Id": "Crossbow",
|
||||||
|
"Name": "Самострелы",
|
||||||
|
"TradeMarketCategory": 56,
|
||||||
|
"ItemClassCategory": 58
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 79,
|
||||||
|
"Id": "Focus",
|
||||||
|
"Name": "Фокусы",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 59
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 80,
|
||||||
|
"Id": "InstanceLocalItem",
|
||||||
|
"Name": "Местные предметы области",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 81,
|
||||||
|
"Id": "SentinelDrone",
|
||||||
|
"Name": "Часовые",
|
||||||
|
"TradeMarketCategory": 51,
|
||||||
|
"ItemClassCategory": 52
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 82,
|
||||||
|
"Id": "MemoryLine",
|
||||||
|
"Name": "Воспоминания",
|
||||||
|
"TradeMarketCategory": 52,
|
||||||
|
"ItemClassCategory": 54
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 83,
|
||||||
|
"Id": "Flail",
|
||||||
|
"Name": "Кистени",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 84,
|
||||||
|
"Id": "Relic",
|
||||||
|
"Name": "Реликвии",
|
||||||
|
"TradeMarketCategory": 54,
|
||||||
|
"ItemClassCategory": 53
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 85,
|
||||||
|
"Id": "SanctumSpecialRelic",
|
||||||
|
"Name": "Священные реликвии",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 53
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 86,
|
||||||
|
"Id": "Breachstone",
|
||||||
|
"Name": "Камни Разлома",
|
||||||
|
"TradeMarketCategory": 37,
|
||||||
|
"ItemClassCategory": 55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 87,
|
||||||
|
"Id": "GiftBox",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 88,
|
||||||
|
"Id": "VaultKey",
|
||||||
|
"Name": "Ключи от хранилищ",
|
||||||
|
"TradeMarketCategory": 38,
|
||||||
|
"ItemClassCategory": 56
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 89,
|
||||||
|
"Id": "ItemisedSanctum",
|
||||||
|
"Name": "Монеты Испытания",
|
||||||
|
"TradeMarketCategory": 38,
|
||||||
|
"ItemClassCategory": 33
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 90,
|
||||||
|
"Id": "DONOTUSE12",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 91,
|
||||||
|
"Id": "UncutSkillGem",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 65
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 92,
|
||||||
|
"Id": "Buckler",
|
||||||
|
"Name": "Баклеры",
|
||||||
|
"TradeMarketCategory": 57,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 93,
|
||||||
|
"Id": "Thrown One Hand Axe",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 94,
|
||||||
|
"Id": "Thrown Two Hand Axe",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 95,
|
||||||
|
"Id": "ConventionTreasure",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 96,
|
||||||
|
"Id": "TrapTool",
|
||||||
|
"Name": "Ловушки",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 63
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 97,
|
||||||
|
"Id": "Crossbow Attachment REMOVE",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 98,
|
||||||
|
"Id": "SkillGemToken",
|
||||||
|
"Name": "Вещи на обмен",
|
||||||
|
"TradeMarketCategory": 39,
|
||||||
|
"ItemClassCategory": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 99,
|
||||||
|
"Id": "Nothing",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 100,
|
||||||
|
"Id": "UltimatumKey",
|
||||||
|
"Name": "Начертанные Ультиматумы",
|
||||||
|
"TradeMarketCategory": 38,
|
||||||
|
"ItemClassCategory": 33
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 101,
|
||||||
|
"Id": "UncutSupportGem",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 65
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 102,
|
||||||
|
"Id": "UncutReservationGem",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 65
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 103,
|
||||||
|
"Id": "Thrown Shield",
|
||||||
|
"Name": "",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 104,
|
||||||
|
"Id": "SoulCore",
|
||||||
|
"Name": "Размещаемое",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 67
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 105,
|
||||||
|
"Id": "TowerAugmentation",
|
||||||
|
"Name": "Плитки",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 68
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 106,
|
||||||
|
"Id": "Omen",
|
||||||
|
"Name": "Предзнаменования",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": 107,
|
||||||
|
"Id": "PinnacleKey",
|
||||||
|
"Name": "Древние ключи",
|
||||||
|
"TradeMarketCategory": null,
|
||||||
|
"ItemClassCategory": null
|
||||||
|
}
|
||||||
|
]
|
||||||
44
renderer/public/.DS_Store/base/unique_mods.json
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "The Beachhead",
|
||||||
|
"basetype": "The Beachhead",
|
||||||
|
"fixedStats": [
|
||||||
|
{
|
||||||
|
"ref": "Base/Armour/BaseArmour",
|
||||||
|
"value": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ref": "Base/Evasion/BaseEvasion",
|
||||||
|
"value": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "The Burden of Leadership",
|
||||||
|
"basetype": "The Burden of Leadership",
|
||||||
|
"fixedStats": [
|
||||||
|
{
|
||||||
|
"ref": "Base/Armour/BaseArmour",
|
||||||
|
"value": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ref": "Base/Evasion/BaseEvasion",
|
||||||
|
"value": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "The Burden of Speed",
|
||||||
|
"basetype": "The Burden of Speed",
|
||||||
|
"fixedStats": [
|
||||||
|
{
|
||||||
|
"ref": "Base/Armour/BaseArmour",
|
||||||
|
"value": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ref": "Base/Evasion/BaseEvasion",
|
||||||
|
"value": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
8
renderer/public/.DS_Store/copy-py-ndjson.sh
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
supported_languages=("en" "ru")
|
||||||
|
|
||||||
|
for lang in "${supported_languages[@]}"; do
|
||||||
|
echo "Copying $lang"
|
||||||
|
cp -R ./vendor/client/pyDumps/$lang/* ./data/$lang/
|
||||||
|
done
|
||||||
4530
renderer/public/.DS_Store/data/cmn-Hant/items.ndjson.old
Normal file
6648
renderer/public/.DS_Store/data/cmn-Hant/stats.ndjson.old
Normal file
41
renderer/public/.DS_Store/data/en/imageFix.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
def get_script_dir():
|
||||||
|
"""Returns the directory where the script is located."""
|
||||||
|
return os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
def read_ndjson(file_path):
|
||||||
|
"""Reads a newline-delimited JSON file and returns a list of parsed JSON objects."""
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as file:
|
||||||
|
return [json.loads(line) for line in file]
|
||||||
|
|
||||||
|
def write_ndjson(file_path, data):
|
||||||
|
"""Writes a list of JSON objects to a newline-delimited JSON file."""
|
||||||
|
with open(file_path, 'w', encoding='utf-8') as file:
|
||||||
|
for item in data:
|
||||||
|
file.write(json.dumps(item) + '\n')
|
||||||
|
|
||||||
|
def update_icons(new_items, old_items):
|
||||||
|
"""Update icons in new_items if they are missing and present in old_items."""
|
||||||
|
old_icons = {item['refName']: item['icon'] for item in old_items if 'icon' in item}
|
||||||
|
|
||||||
|
for new_item in new_items:
|
||||||
|
ref_name = new_item['refName']
|
||||||
|
if new_item.get('icon') == "%NOT_FOUND%" and ref_name in old_icons:
|
||||||
|
new_item['icon'] = old_icons[ref_name]
|
||||||
|
|
||||||
|
return new_items
|
||||||
|
|
||||||
|
# Determine the directory this script is in
|
||||||
|
script_dir = get_script_dir()
|
||||||
|
|
||||||
|
# Load the old and new items from the respective files in the script's directory
|
||||||
|
old_items = read_ndjson(os.path.join(script_dir, 'items.ndjson.old'))
|
||||||
|
new_items = read_ndjson(os.path.join(script_dir, 'items.ndjson'))
|
||||||
|
|
||||||
|
# Update new_items with icons from old_items where applicable
|
||||||
|
updated_new_items = update_icons(new_items, old_items)
|
||||||
|
|
||||||
|
# Write the updated new items back to the new file or a new file as needed
|
||||||
|
write_ndjson(os.path.join(script_dir, 'items.ndjson'), updated_new_items)
|
||||||
3059
renderer/public/.DS_Store/data/en/items.ndjson
Normal file
4527
renderer/public/.DS_Store/data/en/items.ndjson.old
Normal file
2931
renderer/public/.DS_Store/data/en/stats.ndjson
Normal file
6681
renderer/public/.DS_Store/data/en/stats.ndjson.old
Normal file
141
renderer/public/.DS_Store/data/interfaces-apt.ts
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
export enum ItemCategory {
|
||||||
|
Map = 'Map',
|
||||||
|
CapturedBeast = 'Captured Beast',
|
||||||
|
MetamorphSample = 'Metamorph Sample',
|
||||||
|
Helmet = 'Helmet',
|
||||||
|
BodyArmour = 'Body Armour',
|
||||||
|
Gloves = 'Gloves',
|
||||||
|
Boots = 'Boots',
|
||||||
|
Shield = 'Shield',
|
||||||
|
Amulet = 'Amulet',
|
||||||
|
Belt = 'Belt',
|
||||||
|
Ring = 'Ring',
|
||||||
|
Flask = 'Flask',
|
||||||
|
AbyssJewel = 'Abyss Jewel',
|
||||||
|
Jewel = 'Jewel',
|
||||||
|
Quiver = 'Quiver',
|
||||||
|
Claw = 'Claw',
|
||||||
|
Bow = 'Bow',
|
||||||
|
Sceptre = 'Sceptre',
|
||||||
|
Wand = 'Wand',
|
||||||
|
FishingRod = 'Fishing Rod',
|
||||||
|
Staff = 'Staff',
|
||||||
|
Warstaff = 'Warstaff',
|
||||||
|
Dagger = 'Dagger',
|
||||||
|
RuneDagger = 'Rune Dagger',
|
||||||
|
OneHandedAxe = 'One-Handed Axe',
|
||||||
|
TwoHandedAxe = 'Two-Handed Axe',
|
||||||
|
OneHandedMace = 'One-Handed Mace',
|
||||||
|
TwoHandedMace = 'Two-Handed Mace',
|
||||||
|
OneHandedSword = 'One-Handed Sword',
|
||||||
|
TwoHandedSword = 'Two-Handed Sword',
|
||||||
|
ClusterJewel = 'Cluster Jewel',
|
||||||
|
HeistBlueprint = 'Heist Blueprint',
|
||||||
|
HeistContract = 'Heist Contract',
|
||||||
|
HeistTool = 'Heist Tool',
|
||||||
|
HeistBrooch = 'Heist Brooch',
|
||||||
|
HeistGear = 'Heist Gear',
|
||||||
|
HeistCloak = 'Heist Cloak',
|
||||||
|
Trinket = 'Trinket',
|
||||||
|
Invitation = 'Invitation',
|
||||||
|
Gem = 'Gem',
|
||||||
|
Currency = 'Currency',
|
||||||
|
DivinationCard = 'Divination Card',
|
||||||
|
Voidstone = 'Voidstone',
|
||||||
|
Sentinel = 'Sentinel',
|
||||||
|
MemoryLine = 'Memory Line',
|
||||||
|
SanctumRelic = 'Sanctum Relic',
|
||||||
|
Tincture = 'Tincture',
|
||||||
|
Charm = 'Charm',
|
||||||
|
Crossbow = 'Crossbow',
|
||||||
|
SkillGem = 'Skill Gem',
|
||||||
|
SupportGem = 'Support Gem',
|
||||||
|
MetaGem = 'Meta Gem',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StatMatcher {
|
||||||
|
string: string
|
||||||
|
advanced?: string
|
||||||
|
negate?: true
|
||||||
|
value?: number
|
||||||
|
oils?: string // Amulet anointment
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum StatBetter {
|
||||||
|
NegativeRoll = -1,
|
||||||
|
PositiveRoll = 1,
|
||||||
|
NotComparable = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Stat {
|
||||||
|
ref: string
|
||||||
|
dp?: true
|
||||||
|
matchers: StatMatcher[]
|
||||||
|
better: StatBetter
|
||||||
|
fromAreaMods?: true
|
||||||
|
fromUberAreaMods?: true
|
||||||
|
fromHeistAreaMods?: true
|
||||||
|
anointments?: Array<{ roll: number, oils: string }> // Ring anointments
|
||||||
|
trade: {
|
||||||
|
inverted?: true
|
||||||
|
option?: true
|
||||||
|
ids: {
|
||||||
|
[type: string]: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DropEntry {
|
||||||
|
query: string[]
|
||||||
|
items: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaseType {
|
||||||
|
name: string
|
||||||
|
refName: string
|
||||||
|
namespace: (
|
||||||
|
'DIVINATION_CARD' |
|
||||||
|
'CAPTURED_BEAST' |
|
||||||
|
'UNIQUE' |
|
||||||
|
'ITEM' |
|
||||||
|
'GEM'
|
||||||
|
)
|
||||||
|
icon: string
|
||||||
|
w?: number
|
||||||
|
h?: number
|
||||||
|
tradeTag?: string
|
||||||
|
tradeDisc?: string
|
||||||
|
disc?: {
|
||||||
|
propAR?: true
|
||||||
|
propEV?: true
|
||||||
|
propES?: true
|
||||||
|
hasImplicit?: { ref: Stat['ref'] }
|
||||||
|
hasExplicit?: { ref: Stat['ref'] }
|
||||||
|
sectionText?: string
|
||||||
|
mapTier?: 'W' | 'Y' | 'R'
|
||||||
|
}
|
||||||
|
// extra info
|
||||||
|
craftable?: {
|
||||||
|
category: string
|
||||||
|
corrupted?: true
|
||||||
|
uniqueOnly?: true
|
||||||
|
}
|
||||||
|
unique?: {
|
||||||
|
base: BaseType['refName']
|
||||||
|
fixedStats?: Array<Stat['ref']>
|
||||||
|
}
|
||||||
|
map?: {
|
||||||
|
screenshot?: string
|
||||||
|
}
|
||||||
|
gem?: {
|
||||||
|
vaal?: true
|
||||||
|
awakened?: true
|
||||||
|
transfigured?: true
|
||||||
|
normalVariant?: BaseType['refName']
|
||||||
|
}
|
||||||
|
armour?: {
|
||||||
|
ar?: [min: number, max: number]
|
||||||
|
ev?: [min: number, max: number]
|
||||||
|
es?: [min: number, max: number]
|
||||||
|
}
|
||||||
|
}
|
||||||
4527
renderer/public/.DS_Store/data/ko/items.ndjson.old
Normal file
6681
renderer/public/.DS_Store/data/ko/stats.ndjson.old
Normal file
4527
renderer/public/.DS_Store/data/ru/items.ndjson.old
Normal file
6681
renderer/public/.DS_Store/data/ru/stats.ndjson.old
Normal file
333
renderer/public/.DS_Store/items.ts
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
import * as fs from 'node:fs'
|
||||||
|
import * as Tables from './vendor/client/tables/index'
|
||||||
|
import { BaseType } from './data/interfaces-apt.js'
|
||||||
|
import * as UNIQUE_FIXED_STATS from './base/unique_mods.json'
|
||||||
|
import { API_ALL_ITEMS, API_BULK_ITEMS, API_ITEM_ICONS } from './vendor/trade-api/index'
|
||||||
|
import * as assert from 'node:assert'
|
||||||
|
import * as path from 'node:path';
|
||||||
|
|
||||||
|
// const MAP_SCREENSHOTS = JSON.parse(
|
||||||
|
// fs.readFileSync(path.join(__dirname, './maps.json'), { encoding: 'utf-8' })
|
||||||
|
// ) as Array<[string, { img: string }]>;
|
||||||
|
|
||||||
|
const ITEM_OVERRIDES = new Map([
|
||||||
|
// BaseItemTypes (Id)
|
||||||
|
['Metadata/Items/Armours/Boots/BootsAtlas1', { icon: 'https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9Cb290cy9Ud29Ub25lZEJvb3RzIiwidyI6MiwiaCI6Miwic2NhbGUiOjF9XQ/93a61b5672/TwoTonedBoots.png', disc: { propEV: true, propES: true } as const }],
|
||||||
|
['Metadata/Items/Armours/Boots/BootsAtlas2', { icon: 'https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9Cb290cy9Ud29Ub25lZEJvb3RzMkIiLCJ3IjoyLCJoIjoyLCJzY2FsZSI6MX1d/c046f556ab/TwoTonedBoots2B.png', disc: { propAR: true, propEV: true } as const }],
|
||||||
|
['Metadata/Items/Armours/Boots/BootsAtlas3', { icon: 'https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9Cb290cy9Ud29Ub25lZEJvb3RzM0IiLCJ3IjoyLCJoIjoyLCJzY2FsZSI6MX1d/e3271c5de1/TwoTonedBoots3B.png', disc: { propAR: true, propES: true } as const }],
|
||||||
|
])
|
||||||
|
|
||||||
|
const EXTRA_ITEMS: BaseType[] = [
|
||||||
|
{ name: 'Blighted Map', refName: 'Blighted Map', namespace: 'ITEM', icon: 'https://i.imgur.com/CRmwRkA.png' },
|
||||||
|
{ name: 'Blight-ravaged Map', refName: 'Blight-ravaged Map', namespace: 'ITEM', icon: 'https://i.imgur.com/FpyXU1v.png' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const ITEM_CATEGORY = new Map([
|
||||||
|
['Helmet', { name: 'Helmet', craftable: true }],
|
||||||
|
['Body Armour', { name: 'Body Armour', craftable: true }],
|
||||||
|
['Gloves', { name: 'Gloves', craftable: true }],
|
||||||
|
['Boots', { name: 'Boots', craftable: true }],
|
||||||
|
['Shield', { name: 'Shield', craftable: true }],
|
||||||
|
['Amulet', { name: 'Amulet', craftable: true }],
|
||||||
|
['Belt', { name: 'Belt', craftable: true }],
|
||||||
|
['Ring', { name: 'Ring', craftable: true }],
|
||||||
|
['LifeFlask', { name: 'Flask', craftable: true }],
|
||||||
|
['ManaFlask', { name: 'Flask', craftable: true }],
|
||||||
|
['UtilityFlask', { name: 'Flask', craftable: true }],
|
||||||
|
// ['AbyssJewel', { name: 'Abyss Jewel', craftable: true }],
|
||||||
|
['Jewel', { name: 'Jewel', craftable: true }],
|
||||||
|
// ['Cluster Jewel', { name: 'Cluster Jewel', craftable: true }], // NOTE: manual
|
||||||
|
['Quiver', { name: 'Quiver', craftable: true }],
|
||||||
|
['Claw', { name: 'Claw', craftable: true }],
|
||||||
|
['Dagger', { name: 'Dagger', craftable: true }],
|
||||||
|
['Bow', { name: 'Bow', craftable: true }],
|
||||||
|
['Sceptre', { name: 'Sceptre', craftable: true }],
|
||||||
|
['Wand', { name: 'Wand', craftable: true }],
|
||||||
|
['FishingRod', { name: 'Fishing Rod', craftable: true }],
|
||||||
|
['Staff', { name: 'Staff', craftable: true }],
|
||||||
|
['Warstaff', { name: 'Warstaff', craftable: true }],
|
||||||
|
['One Hand Axe', { name: 'One-Handed Axe', craftable: true }],
|
||||||
|
['Two Hand Axe', { name: 'Two-Handed Axe', craftable: true }],
|
||||||
|
['One Hand Mace', { name: 'One-Handed Mace', craftable: true }],
|
||||||
|
['Two Hand Mace', { name: 'Two-Handed Mace', craftable: true }],
|
||||||
|
['One Hand Sword', { name: 'One-Handed Sword', craftable: true }],
|
||||||
|
// ['Thrusting One Hand Sword', { name: 'One-Handed Sword', craftable: true }],
|
||||||
|
['Two Hand Sword', { name: 'Two-Handed Sword', craftable: true }],
|
||||||
|
|
||||||
|
['Relic', { name: 'Sanctum Relic', craftable: true }],
|
||||||
|
['Tincture', { name: 'Tincture', craftable: true }],
|
||||||
|
['AnimalCharm', { name: 'Charm', craftable: true }],
|
||||||
|
['ExpeditionLogbook', { name: 'Expedition Logbook', craftable: true }],
|
||||||
|
[`Invitation`, { name: `Invitation`, craftable: true }], // NOTE: manual
|
||||||
|
['MemoryLine', { name: 'Memory Line', craftable: true }],
|
||||||
|
['HeistBlueprint', { name: 'Heist Blueprint', craftable: true }],
|
||||||
|
['HeistContract', { name: 'Heist Contract', craftable: true }],
|
||||||
|
['HeistEquipmentTool', { name: 'Heist Tool', craftable: true }],
|
||||||
|
['HeistEquipmentReward', { name: 'Heist Brooch', craftable: true }],
|
||||||
|
['HeistEquipmentWeapon', { name: 'Heist Gear', craftable: true }],
|
||||||
|
['HeistEquipmentUtility', { name: 'Heist Cloak', craftable: true }],
|
||||||
|
['Trinket', { name: 'Trinket', craftable: true }],
|
||||||
|
['UniqueFragment', { name: 'Unique Fragment', craftable: true, uniqueOnly: true }],
|
||||||
|
|
||||||
|
['NecropolisPack', {}],
|
||||||
|
['ItemisedCorpse', {}],
|
||||||
|
['ItemisedSanctum', {}],
|
||||||
|
['MiscMapItem', {}],
|
||||||
|
['Breachstone', {}],
|
||||||
|
['VaultKey', {}],
|
||||||
|
['StackableCurrency', {}],
|
||||||
|
['DelveStackableSocketableCurrency', {}],
|
||||||
|
['IncubatorStackable', {}],
|
||||||
|
['MapFragment', {}],
|
||||||
|
['MetamorphosisDNA', {}],
|
||||||
|
|
||||||
|
|
||||||
|
['Spear', { name: 'Spear', craftable: true }],
|
||||||
|
['Flail', { name: 'Flail', craftable: true }],
|
||||||
|
['Crossbow', { name: 'Crossbow', craftable: true }],
|
||||||
|
['TrapTool', { name: 'Trap Tool', craftable: true }],
|
||||||
|
])
|
||||||
|
const ArmourTypes = Tables.ArmourTypes()
|
||||||
|
function getArmourField(baseRid: number): BaseType['armour'] {
|
||||||
|
const found = ArmourTypes.find(row => row.BaseItemTypesKey === baseRid)
|
||||||
|
return (found) ? {
|
||||||
|
ar: (found.Armour > 0) ? [found.Armour, found.Armour] : undefined,
|
||||||
|
ev: (found.Evasion > 0) ? [found.Evasion, found.Evasion] : undefined,
|
||||||
|
es: (found.EnergyShield > 0) ? [found.EnergyShield, found.EnergyShield] : undefined,
|
||||||
|
} : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeGenerator2Bases() {
|
||||||
|
const ITEM_CLASS_BLACKLIST = new Set([
|
||||||
|
'DelveSocketableCurrency',
|
||||||
|
'Microtransaction',
|
||||||
|
'HiddenItem',
|
||||||
|
'QuestItem',
|
||||||
|
'LabyrinthItem',
|
||||||
|
'LabyrinthTrinket',
|
||||||
|
'Leaguestone',
|
||||||
|
'Currency',
|
||||||
|
'Incubator',
|
||||||
|
'SanctumSpecialRelic',
|
||||||
|
'HideoutDoodad',
|
||||||
|
'LabyrinthMapItem',
|
||||||
|
'PantheonSoul',
|
||||||
|
'IncursionItem',
|
||||||
|
'HeistObjective',
|
||||||
|
'AtlasUpgradeItem',
|
||||||
|
'ArchnemesisMod',
|
||||||
|
'SentinelDrone',
|
||||||
|
'GiftBox',
|
||||||
|
'InstanceLocalItem',
|
||||||
|
'Gold',
|
||||||
|
'Map', // ++
|
||||||
|
'DivinationCard', // ++
|
||||||
|
'Active Skill Gem', // ++
|
||||||
|
'Support Skill Gem', // ++
|
||||||
|
'Meta Skill Gem', // ++
|
||||||
|
'SoulCore',
|
||||||
|
'UncutSkillGem',
|
||||||
|
'UncutSupportGem',
|
||||||
|
'ConventionTreasure',
|
||||||
|
'SkillGemToken',
|
||||||
|
'PinnacleKey',
|
||||||
|
'UltimatumKey',
|
||||||
|
'UncutReservationGem',
|
||||||
|
'TowerAugmentation',
|
||||||
|
'Omen',
|
||||||
|
'Focus',
|
||||||
|
])
|
||||||
|
|
||||||
|
const ItemClasses = Tables.ItemClasses()
|
||||||
|
const Tags = Tables.Tags()
|
||||||
|
|
||||||
|
const bulkItems = API_BULK_ITEMS().filter(s =>
|
||||||
|
s.id !== 'Coffins' &&
|
||||||
|
s.id !== 'Cards' &&
|
||||||
|
s.id !== 'Sanctum' &&
|
||||||
|
!s.id.startsWith('Maps')
|
||||||
|
).flatMap(s => s.entries.map((i => ({ ...i, image: i.image && `https://web.poecdn.com${i.image}` }))))
|
||||||
|
|
||||||
|
const baseIcons = API_ITEM_ICONS().filter(i => !i.unique)
|
||||||
|
|
||||||
|
|
||||||
|
const baseTypes = Tables.BaseItemTypes()
|
||||||
|
.filter(row => {
|
||||||
|
const itemClass = ItemClasses[row.ItemClassesKey as unknown as number].Id
|
||||||
|
if (!ITEM_CATEGORY.has(itemClass)) {
|
||||||
|
assert.ok(ITEM_CLASS_BLACKLIST.has(itemClass), itemClass)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !((
|
||||||
|
row.Name !== 'Albino Rhoa Feather' &&
|
||||||
|
row.Name !== 'Fishing Rod' &&
|
||||||
|
row.Name !== 'Two-Stone Ring' &&
|
||||||
|
row.Name !== 'Two-Toned Boots' &&
|
||||||
|
(
|
||||||
|
row.Name === 'Imprinted Bestiary Orb' ||
|
||||||
|
row.Name === 'Uncarved Gemstone' ||
|
||||||
|
(itemClass === 'ItemisedSanctum' && row.TagsKeys.length < 2) ||
|
||||||
|
row.SiteVisibility !== 1
|
||||||
|
)
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.map(row => ({
|
||||||
|
...row,
|
||||||
|
armour: getArmourField(row._index),
|
||||||
|
tradeTag: bulkItems.find(e => e.text === row.Name)?.id,
|
||||||
|
icon: bulkItems.find(e => e.text === row.Name)?.image ??
|
||||||
|
baseIcons.find(e => e.baseType === row.Name)?.icon
|
||||||
|
}))
|
||||||
|
|
||||||
|
return (lang: string) => {
|
||||||
|
const BaseItemTypes = Tables.BaseItemTypes(lang)
|
||||||
|
|
||||||
|
return baseTypes.map<BaseType>(row => {
|
||||||
|
let itemClass = ItemClasses[row.ItemClassesKey as unknown as number].Id
|
||||||
|
if (itemClass === 'Jewel' && row.TagsKeys.some(rid => Tags[rid as unknown as number].Id.startsWith('expansion_jewel_'))) {
|
||||||
|
itemClass = 'Cluster Jewel'
|
||||||
|
}
|
||||||
|
if (itemClass === 'MiscMapItem' && row.TagsKeys.some(rid =>
|
||||||
|
Tags[rid as unknown as number].Id === 'maven_map' || Tags[rid as unknown as number].Id === 'primordial_map'
|
||||||
|
)) {
|
||||||
|
itemClass = 'Invitation'
|
||||||
|
}
|
||||||
|
|
||||||
|
const category = ITEM_CATEGORY.get(itemClass) ?? assert.fail()
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: BaseItemTypes[row._index].Name,
|
||||||
|
refName: row.Name,
|
||||||
|
namespace: 'ITEM',
|
||||||
|
craftable: (category.craftable)
|
||||||
|
? {
|
||||||
|
category: category.name,
|
||||||
|
corrupted: row.IsCorrupted || undefined,
|
||||||
|
uniqueOnly: category.uniqueOnly || undefined
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
tradeTag: row.tradeTag,
|
||||||
|
armour: row.armour,
|
||||||
|
icon: (category.uniqueOnly) ? '' : (row.icon ?? '%NOT_FOUND%'),
|
||||||
|
w: (row.Width > 1) ? row.Width : undefined,
|
||||||
|
h: (row.Height > 1) ? row.Height : undefined,
|
||||||
|
...(ITEM_OVERRIDES.get(row.Id) ?? {} as object)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeGenerator4Uniques() {
|
||||||
|
const ndjsonBaseTypes = [
|
||||||
|
// ...makeGenerator2Map()('en'),
|
||||||
|
...makeGenerator2Bases()('en')
|
||||||
|
]
|
||||||
|
|
||||||
|
const WORDLIST_UNIQUE = 6
|
||||||
|
const Words = Tables.Words()
|
||||||
|
|
||||||
|
const UNIQUE_ICONS = API_ITEM_ICONS().filter(i => i.unique)
|
||||||
|
|
||||||
|
const tradeUniqueItems = API_ALL_ITEMS().flatMap(s => s.entries)
|
||||||
|
.filter(i => i.flags?.unique && (!i.disc || i.disc === 'warfortheatlas'))
|
||||||
|
|
||||||
|
const words = Tables.UniquesStashLayout()
|
||||||
|
.filter(row =>
|
||||||
|
row.ShowIfEmptyChallengeLeague &&
|
||||||
|
row.RenamedVersion === null &&
|
||||||
|
row.UniqueStashTypesKey !== 20 /* Watchstone */
|
||||||
|
)
|
||||||
|
.map(row => Words[row.WordsKey])
|
||||||
|
// .filter(row =>
|
||||||
|
// row.Text2 !== "UNIQUE_NAME_NOT_ON_TRADE_YET" &&
|
||||||
|
// true)
|
||||||
|
|
||||||
|
const extraUniqueItems = Words
|
||||||
|
.filter(row => (row.Wordlist === WORDLIST_UNIQUE) && (
|
||||||
|
// Unique Pieces
|
||||||
|
row.Text2.startsWith('First Piece of ') ||
|
||||||
|
row.Text2.startsWith('Second Piece of ') ||
|
||||||
|
row.Text2.startsWith('Third Piece of ') ||
|
||||||
|
row.Text2.startsWith('Fourth Piece of ')
|
||||||
|
))
|
||||||
|
words.push(...extraUniqueItems)
|
||||||
|
|
||||||
|
return (lang: string) => {
|
||||||
|
const Words = Tables.Words(lang)
|
||||||
|
|
||||||
|
return words.flatMap(row => {
|
||||||
|
const baseTypes = tradeUniqueItems.filter(i => i.name === row.Text2)
|
||||||
|
assert.ok(baseTypes.length >= 1, row.Text2)
|
||||||
|
|
||||||
|
if (baseTypes.length > 1) {
|
||||||
|
if (row.Text2 !== 'Grand Spectrum' &&
|
||||||
|
row.Text2 !== 'Combat Focus' &&
|
||||||
|
row.Text2 !== "Precursor's Emblem" &&
|
||||||
|
row.Text2 !== "Doryani's Delusion" &&
|
||||||
|
row.Text2 !== "The Beachhead"
|
||||||
|
) {
|
||||||
|
assert.ok(baseTypes.length === 1, row.Text2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseTypes.flatMap<BaseType>(({ type: baseTypeString }) => {
|
||||||
|
const baseTypeDb = ndjsonBaseTypes.find(entry => entry.refName === baseTypeString)
|
||||||
|
assert.ok(baseTypeDb, `Basetype "${baseTypeString}" of unique item "${row.Text2}" not found`)
|
||||||
|
|
||||||
|
const template: BaseType = {
|
||||||
|
name: Words[row._index].Text2,
|
||||||
|
refName: row.Text2,
|
||||||
|
namespace: 'UNIQUE' as const,
|
||||||
|
unique: {
|
||||||
|
base: baseTypeString,
|
||||||
|
fixedStats: UNIQUE_FIXED_STATS.find(entry =>
|
||||||
|
entry.name === row.Text2 &&
|
||||||
|
entry.basetype === baseTypeString
|
||||||
|
)?.fixedStats.map(_ => _.ref)
|
||||||
|
},
|
||||||
|
map: (baseTypeDb.craftable?.category === 'Map')
|
||||||
|
? {
|
||||||
|
screenshot: "MAP_SCREENSHOTS.find(([name]) => name === row.Text2)?.[1].img"
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
icon: UNIQUE_ICONS.find(i => i.unique === row.Text2 && i.baseType === baseTypeString)?.icon
|
||||||
|
?? '%NOT_FOUND%'
|
||||||
|
}
|
||||||
|
if (row.Text2 === 'The Beachhead') {
|
||||||
|
return [
|
||||||
|
'HarbingerLow/Unique', 'HarbingerMid/Unique', 'HarbingerHigh/Unique',
|
||||||
|
].map<BaseType>(baseId => ({
|
||||||
|
...template,
|
||||||
|
...(ITEM_OVERRIDES.get(baseId) ?? assert.fail())
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return [template]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
; (async function main() {
|
||||||
|
const generators = [
|
||||||
|
// makeGenerator1Beasts(),
|
||||||
|
// makeGenerator2Map(),
|
||||||
|
// makeGenerator2Divcard(),
|
||||||
|
// makeGenerator2Gems(),
|
||||||
|
makeGenerator2Bases(),
|
||||||
|
// makeGenerator4Uniques(),
|
||||||
|
(_lang: string) => EXTRA_ITEMS
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const lang of ['en']) {
|
||||||
|
const items = generators.flatMap(g => g(lang))
|
||||||
|
items.sort((a, b) => a.namespace.localeCompare(b.namespace) || a.refName.localeCompare(b.refName))
|
||||||
|
|
||||||
|
|
||||||
|
const jsonLines = Array.from(
|
||||||
|
new Set(items.map(item => JSON.stringify(item))))
|
||||||
|
|
||||||
|
const filePath = path.join(__dirname, 'data', lang, 'items.ndjson');
|
||||||
|
fs.writeFileSync(filePath, jsonLines.join('\n') + '\n');
|
||||||
|
|
||||||
|
}
|
||||||
|
})()
|
||||||
269
renderer/public/.DS_Store/package-lock.json
generated
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
{
|
||||||
|
"name": "data-importer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "data-importer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^8.14.0",
|
||||||
|
"acorn-walk": "^8.3.4",
|
||||||
|
"arg": "^4.1.3",
|
||||||
|
"create-require": "^1.1.1",
|
||||||
|
"diff": "^4.0.2",
|
||||||
|
"make-error": "^1.3.6",
|
||||||
|
"ooz-wasm": "^2.0.0",
|
||||||
|
"pathofexile-dat": "^11.0.1",
|
||||||
|
"pathofexile-dat-schema": "^6.0.1",
|
||||||
|
"undici-types": "^6.20.0",
|
||||||
|
"v8-compile-cache-lib": "^3.0.1",
|
||||||
|
"yn": "^3.1.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"typescript": "^5.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@cspotcode/source-map-support": {
|
||||||
|
"version": "0.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||||
|
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/trace-mapping": "0.3.9"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@jridgewell/resolve-uri": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@jridgewell/sourcemap-codec": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@jridgewell/trace-mapping": {
|
||||||
|
"version": "0.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||||
|
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/resolve-uri": "^3.0.3",
|
||||||
|
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tsconfig/node10": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@tsconfig/node12": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@tsconfig/node14": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@tsconfig/node16": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "22.10.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
|
||||||
|
"integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~6.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/acorn": {
|
||||||
|
"version": "8.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||||
|
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"acorn": "bin/acorn"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/acorn-walk": {
|
||||||
|
"version": "8.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||||
|
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^8.11.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/arg": {
|
||||||
|
"version": "4.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||||
|
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/create-require": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/diff": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/make-error": {
|
||||||
|
"version": "1.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||||
|
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/ooz-wasm": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ooz-wasm/-/ooz-wasm-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Ewk+Vga2m9niFGV5qT+4EKfBnFEQSQfnTdOWSlnQcpDB2OAdk7TpRHfKqxLSLhDKRjKjw9R+sGlOreWW8ABR0A==",
|
||||||
|
"license": "GPL-3.0-or-later"
|
||||||
|
},
|
||||||
|
"node_modules/pathofexile-dat": {
|
||||||
|
"version": "11.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pathofexile-dat/-/pathofexile-dat-11.0.1.tgz",
|
||||||
|
"integrity": "sha512-q2mvVLaEAk3pPgYYZF/hSQB9xcv6ifaAHiIw26WqxdUIlcGPSCGbp1EmkDdyk/1VF6Qn2iegvY+nESiB8bJmYw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ooz-wasm": "^2.0.0",
|
||||||
|
"pathofexile-dat-schema": "^6.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"pathofexile-dat": "dist/cli/run.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pathofexile-dat-schema": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pathofexile-dat-schema/-/pathofexile-dat-schema-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-VP8dc2KXqM0KTQw5n6SvO0rQVLJeZil79ReRwbb7z7M8KT7r5qVYkGm5Klf8tzk5aVxyexrX+52Xj4C2mSxF5g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/ts-node": {
|
||||||
|
"version": "10.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||||
|
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@cspotcode/source-map-support": "^0.8.0",
|
||||||
|
"@tsconfig/node10": "^1.0.7",
|
||||||
|
"@tsconfig/node12": "^1.0.7",
|
||||||
|
"@tsconfig/node14": "^1.0.0",
|
||||||
|
"@tsconfig/node16": "^1.0.2",
|
||||||
|
"acorn": "^8.4.1",
|
||||||
|
"acorn-walk": "^8.1.1",
|
||||||
|
"arg": "^4.1.0",
|
||||||
|
"create-require": "^1.1.0",
|
||||||
|
"diff": "^4.0.1",
|
||||||
|
"make-error": "^1.1.1",
|
||||||
|
"v8-compile-cache-lib": "^3.0.1",
|
||||||
|
"yn": "3.1.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"ts-node": "dist/bin.js",
|
||||||
|
"ts-node-cwd": "dist/bin-cwd.js",
|
||||||
|
"ts-node-esm": "dist/bin-esm.js",
|
||||||
|
"ts-node-script": "dist/bin-script.js",
|
||||||
|
"ts-node-transpile-only": "dist/bin-transpile.js",
|
||||||
|
"ts-script": "dist/bin-script-deprecated.js"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@swc/core": ">=1.2.50",
|
||||||
|
"@swc/wasm": ">=1.2.50",
|
||||||
|
"@types/node": "*",
|
||||||
|
"typescript": ">=2.7"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@swc/core": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@swc/wasm": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
|
||||||
|
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "6.20.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||||
|
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/v8-compile-cache-lib": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/yn": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
renderer/public/.DS_Store/package.json
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "data-importer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^8.14.0",
|
||||||
|
"acorn-walk": "^8.3.4",
|
||||||
|
"arg": "^4.1.3",
|
||||||
|
"create-require": "^1.1.1",
|
||||||
|
"diff": "^4.0.2",
|
||||||
|
"make-error": "^1.3.6",
|
||||||
|
"ooz-wasm": "^2.0.0",
|
||||||
|
"pathofexile-dat": "^11.0.1",
|
||||||
|
"pathofexile-dat-schema": "^6.0.1",
|
||||||
|
"undici-types": "^6.20.0",
|
||||||
|
"v8-compile-cache-lib": "^3.0.1",
|
||||||
|
"yn": "^3.1.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"typescript": "^5.7.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"start": "node dist/index.js",
|
||||||
|
"items": "ts-node items.ts",
|
||||||
|
"stats": "ts-node stats.ts",
|
||||||
|
"copy-files": "cp -R EXPORT/tables/English/* vendor/client/tables/",
|
||||||
|
"push-ndjson": "bash ./push-ndjson.sh",
|
||||||
|
"anon-vodka-python": "python ./vendor/client/parser.py",
|
||||||
|
"langs-anon-vodka-python": "python ./vendor/client/parserRunner.py",
|
||||||
|
"temp-images": "python ./data/en/imageFix.py",
|
||||||
|
"copy-py-ndjson": "bash ./copy-py-ndjson.sh",
|
||||||
|
"fetch-json": "bash ./pull-json.sh"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
45
renderer/public/.DS_Store/pull-json.sh
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Array of language codes and their corresponding base URLs
|
||||||
|
declare -A lang_urls=(
|
||||||
|
["en"]="https://www.pathofexile.com"
|
||||||
|
["ru"]="https://ru.pathofexile.com"
|
||||||
|
["ko"]="https://poe.game.daum.net"
|
||||||
|
)
|
||||||
|
|
||||||
|
# URLs to fetch JSON from (relative paths)
|
||||||
|
urls=(
|
||||||
|
"/api/trade2/data/filters"
|
||||||
|
"/api/trade2/data/stats"
|
||||||
|
"/api/trade2/data/items"
|
||||||
|
"/api/trade2/data/static"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Loop through each language
|
||||||
|
for lang in "${!lang_urls[@]}"; do
|
||||||
|
# Directory to save the JSON files for the current language
|
||||||
|
output_dir="./vendor/json-api/$lang"
|
||||||
|
|
||||||
|
# Create output directory if it doesn't exist
|
||||||
|
mkdir -p "$output_dir"
|
||||||
|
|
||||||
|
# Loop through each URL
|
||||||
|
for relative_url in "${urls[@]}"; do
|
||||||
|
# Construct the full URL
|
||||||
|
url="${lang_urls[$lang]}$relative_url"
|
||||||
|
|
||||||
|
# Extract the filename from the relative URL
|
||||||
|
filename=$(basename "$relative_url")
|
||||||
|
|
||||||
|
echo "Fetching JSON from: $url for language: $lang"
|
||||||
|
|
||||||
|
# Fetch the JSON data and save it to a file
|
||||||
|
curl -s "$url" -o "$output_dir/$filename.json"
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Saved JSON to: $output_dir/$filename.json"
|
||||||
|
else
|
||||||
|
echo "Failed to fetch JSON from: $url"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
21
renderer/public/.DS_Store/push-ndjson.sh
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script pushes data from our data/en directory to the actual data/en directory
|
||||||
|
|
||||||
|
# Get the current directory
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
|
||||||
|
# Get the data directory
|
||||||
|
DATA_DIR="./data"
|
||||||
|
SUPPORTED_LANG=("en" "ru")
|
||||||
|
# Get all *.ndjson files in the data directory
|
||||||
|
|
||||||
|
for lang in "${SUPPORTED_LANG[@]}"; do
|
||||||
|
FILES=$(find $DATA_DIR/$lang -name "*.ndjson")
|
||||||
|
|
||||||
|
# Loop through each file and push it to the actual data directory, overwriting any existing files
|
||||||
|
for file in $FILES; do
|
||||||
|
echo "Pushing $file to data/$lang"
|
||||||
|
cp $file ../data/$lang
|
||||||
|
done
|
||||||
|
done
|
||||||
125
renderer/public/.DS_Store/stats.ts
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
import { Stat } from "./data/interfaces-apt";
|
||||||
|
import { Stats } from "./vendor/client/tables/index";
|
||||||
|
import * as fs from "node:fs";
|
||||||
|
import * as path from "node:path";
|
||||||
|
import { API_STATS } from "./vendor/trade-api";
|
||||||
|
import { StatEntry } from "./vendor/trade-api/index-interfaces";
|
||||||
|
|
||||||
|
export function makeGeneratorStats(): (lang: string) => Stat[] {
|
||||||
|
const stats = API_STATS();
|
||||||
|
const statsFlattened = stats.flatMap((s) => s.entries);
|
||||||
|
const addStatId = (s: StatEntry) => {
|
||||||
|
return {
|
||||||
|
...s,
|
||||||
|
statId: s.id.substring(s.type.length + 1),
|
||||||
|
statIdNumber: s.id.substring(s.type.length + 1 + 5) as unknown as number,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const statsWithStatId = statsFlattened.map(addStatId);
|
||||||
|
|
||||||
|
const statsGroupedByStatId = statsWithStatId.reduce(
|
||||||
|
(acc, curr) => {
|
||||||
|
const statId = curr.statId;
|
||||||
|
if (acc[statId]) {
|
||||||
|
acc[statId].push(curr);
|
||||||
|
} else {
|
||||||
|
acc[statId] = [curr];
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as Record<string, StatEntry[]>,
|
||||||
|
);
|
||||||
|
|
||||||
|
const FormatRef = (ref: string) => {
|
||||||
|
// Get all parts of string in [ ]
|
||||||
|
|
||||||
|
let outString = "";
|
||||||
|
|
||||||
|
for (let i = 0; i < ref.length; i++) {
|
||||||
|
if (ref[i] === "[") {
|
||||||
|
i++;
|
||||||
|
let localOutString = "";
|
||||||
|
while (ref[i] !== "]") {
|
||||||
|
if (ref[i] === "|") {
|
||||||
|
localOutString = "";
|
||||||
|
} else {
|
||||||
|
localOutString += ref[i];
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
outString += localOutString;
|
||||||
|
} else {
|
||||||
|
outString += ref[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outString;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (lang: string) => {
|
||||||
|
const statsArray: Stat[] = [];
|
||||||
|
|
||||||
|
for (const statId in statsGroupedByStatId) {
|
||||||
|
const statEntries = statsGroupedByStatId[statId];
|
||||||
|
const combinedStat = {
|
||||||
|
ref: FormatRef(statEntries[0].text),
|
||||||
|
better: 0,
|
||||||
|
matchers: [{ string: "StatMatcher" }],
|
||||||
|
trade: {
|
||||||
|
ids: {
|
||||||
|
...(statEntries.filter((e) => e.type == "explicit").length > 0 && {
|
||||||
|
explicit: statEntries
|
||||||
|
.filter((e) => e.type == "explicit")
|
||||||
|
.map((e) => e.id),
|
||||||
|
}),
|
||||||
|
...(statEntries.filter((e) => e.type == "implicit").length > 0 && {
|
||||||
|
implicit: statEntries
|
||||||
|
.filter((e) => e.type == "implicit")
|
||||||
|
.map((e) => e.id),
|
||||||
|
}),
|
||||||
|
...(statEntries.filter((e) => e.type == "fractured").length > 0 && {
|
||||||
|
fractured: statEntries
|
||||||
|
.filter((e) => e.type == "fractured")
|
||||||
|
.map((e) => e.id),
|
||||||
|
}),
|
||||||
|
...(statEntries.filter((e) => e.type == "scourge").length > 0 && {
|
||||||
|
scourge: statEntries
|
||||||
|
.filter((e) => e.type == "scourge")
|
||||||
|
.map((e) => e.id),
|
||||||
|
}),
|
||||||
|
...(statEntries.filter((e) => e.type == "crafted").length > 0 && {
|
||||||
|
crafted: statEntries
|
||||||
|
.filter((e) => e.type == "crafted")
|
||||||
|
.map((e) => e.id),
|
||||||
|
}),
|
||||||
|
...(statEntries.filter((e) => e.type == "pseudo").length > 0 && {
|
||||||
|
pseudo: statEntries
|
||||||
|
.filter((e) => e.type == "pseudo")
|
||||||
|
.map((e) => e.id),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
statsArray.push(combinedStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
return statsArray;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
(async function main() {
|
||||||
|
const generators = [makeGeneratorStats()];
|
||||||
|
|
||||||
|
for (const lang of ["en"]) {
|
||||||
|
const items = generators.flatMap((g) => g(lang));
|
||||||
|
items.sort((a, b) => a.ref.localeCompare(b.ref));
|
||||||
|
|
||||||
|
const jsonLines = Array.from(
|
||||||
|
new Set(items.map((item) => JSON.stringify(item))),
|
||||||
|
);
|
||||||
|
|
||||||
|
const filePath = path.join(__dirname, "data", lang, "stats.ndjson");
|
||||||
|
fs.writeFileSync(filePath, jsonLines.join("\n") + "\n");
|
||||||
|
}
|
||||||
|
})();
|
||||||
105
renderer/public/.DS_Store/tsconfig.json
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||||
|
/* Projects */
|
||||||
|
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||||
|
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||||
|
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||||
|
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||||
|
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||||
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||||
|
/* Language and Environment */
|
||||||
|
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||||
|
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||||
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||||
|
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||||
|
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||||
|
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||||
|
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||||
|
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||||
|
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||||
|
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||||
|
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||||
|
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||||
|
/* Modules */
|
||||||
|
"module": "commonjs", /* Specify what module code is generated. */
|
||||||
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||||
|
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||||
|
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||||
|
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
|
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||||
|
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||||
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
|
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||||
|
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||||
|
// "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
|
||||||
|
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||||
|
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||||
|
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||||
|
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
|
||||||
|
"resolveJsonModule": true, /* Enable importing .json files. */
|
||||||
|
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||||
|
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||||
|
/* JavaScript Support */
|
||||||
|
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||||
|
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||||
|
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||||
|
"outDir": "./EXPORT", // Specify the output directory
|
||||||
|
"rootDir": "./",
|
||||||
|
/* Emit */
|
||||||
|
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||||
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||||
|
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||||
|
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||||
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||||
|
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||||
|
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||||
|
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
||||||
|
// "removeComments": true, /* Disable emitting comments. */
|
||||||
|
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||||
|
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||||
|
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||||
|
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||||
|
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||||
|
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||||
|
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||||
|
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||||
|
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||||
|
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||||
|
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||||
|
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||||
|
/* Interop Constraints */
|
||||||
|
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||||
|
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||||
|
// "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
|
||||||
|
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||||
|
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||||
|
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||||
|
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||||
|
/* Type Checking */
|
||||||
|
"strict": true, /* Enable all strict type-checking options. */
|
||||||
|
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||||
|
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||||
|
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||||
|
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||||
|
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||||
|
// "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
|
||||||
|
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||||
|
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||||
|
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||||
|
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||||
|
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||||
|
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||||
|
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||||
|
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||||
|
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||||
|
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||||
|
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||||
|
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||||
|
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||||
|
/* Completeness */
|
||||||
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||||
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||||
|
}
|
||||||
|
}
|
||||||
12
renderer/public/.DS_Store/types/global.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
declare module './base/unique_mods.json.js' {
|
||||||
|
interface FixedStat {
|
||||||
|
ref: string;
|
||||||
|
value: number;
|
||||||
|
}
|
||||||
|
interface UniqueFixedStat {
|
||||||
|
name: string;
|
||||||
|
basetype: string;
|
||||||
|
fixedStats: FixedStat[];
|
||||||
|
}
|
||||||
|
export const UNIQUE_FIXED_STATS: UniqueFixedStat[]; // Replace `any` with a more specific type if possible
|
||||||
|
}
|
||||||
509
renderer/public/.DS_Store/vendor/client/parser.py
vendored
Normal file
@@ -0,0 +1,509 @@
|
|||||||
|
"""Tries to prepare the necessary data for poe-trade to work properly.
|
||||||
|
It requires all files from
|
||||||
|
Path of Exile 2/Bundles2/_.index.bin/metadata/statdescriptions
|
||||||
|
NOT
|
||||||
|
Path of Exile 2/Bundles2/_.index.bin/metadata/statdescriptions/specific_skill_stat_descriptions
|
||||||
|
to be in the descriptions folder
|
||||||
|
|
||||||
|
NOTE: This may or may not contain all the necessary data, as the parser is not perfect and neither is the data
|
||||||
|
For example: Unique armor items are missing the "armour" tag, which is required for poe-trade to work properly
|
||||||
|
|
||||||
|
Credits and Resources:
|
||||||
|
SnosMe - https://github.com/SnosMe/poe-dat-viewer
|
||||||
|
SnosMe - https://github.com/SnosMe/awakened-poe-trade
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
class Parser:
|
||||||
|
def get_script_dir(self):
|
||||||
|
"""Returns the directory where the script is located."""
|
||||||
|
return os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
def load_file(self, file):
|
||||||
|
return json.loads(open(f"{self.base_dir}/{self.lang}/{file}.json").read())
|
||||||
|
|
||||||
|
def __init__(self, lang="en"):
|
||||||
|
self.lang = lang
|
||||||
|
|
||||||
|
self.cwd = self.get_script_dir()
|
||||||
|
self.base_dir = self.cwd + "/tables/"
|
||||||
|
self.out_dir = self.cwd + f"/pyDumps/{self.lang}"
|
||||||
|
self.base_items = self.load_file("BaseItemTypes")
|
||||||
|
self.item_classes = self.load_file("ItemClasses")
|
||||||
|
self.item_class_categories = self.load_file("ItemClassCategories")
|
||||||
|
self.armour_types = self.load_file("ArmourTypes")
|
||||||
|
self.weapon_types = self.load_file("WeaponTypes")
|
||||||
|
self.skill_gems = self.load_file("SkillGems")
|
||||||
|
self.skill_gem_info = self.load_file("SkillGemInfo")
|
||||||
|
self.stats_file = self.load_file("Stats")
|
||||||
|
self.translation_files = os.listdir(f"{self.cwd}/descriptions")
|
||||||
|
self.mods_file = self.load_file("Mods")
|
||||||
|
# NOTE: could need to add local here?
|
||||||
|
self.trade_stats = json.loads(
|
||||||
|
open(f"{self.cwd}/../json-api/en/stats.json").read()
|
||||||
|
) # content of https://www.pathofexile.com/api/trade2/data/stats
|
||||||
|
self.trade_items = json.loads(
|
||||||
|
open(f"{self.cwd}/../json-api/en/items.json").read()
|
||||||
|
) # content of https://www.pathofexile.com/api/trade2/data/items
|
||||||
|
self.trade_exchange_items = json.loads(
|
||||||
|
open(f"{self.cwd}/../json-api/en/static.json").read()
|
||||||
|
) # content of https://www.pathofexile.com/api/trade2/data/static
|
||||||
|
|
||||||
|
self.items = {}
|
||||||
|
self.unique_items = []
|
||||||
|
self.parsed_item_class_categories = {}
|
||||||
|
self.parsed_item_classes = {}
|
||||||
|
self.stats = {}
|
||||||
|
self.stats_trade_ids = {}
|
||||||
|
self.mod_translations = {}
|
||||||
|
self.mods = {}
|
||||||
|
self.matchers_no_trade_ids = []
|
||||||
|
|
||||||
|
def make_poe_cdn_url(self, path):
|
||||||
|
return urllib.parse.urljoin("https://web.poecdn.com/", path)
|
||||||
|
|
||||||
|
def convert_stat_name(self, stat):
|
||||||
|
stat = stat.strip()
|
||||||
|
open_square_bracket = stat.find("[")
|
||||||
|
close_square_bracket = stat.find("]")
|
||||||
|
|
||||||
|
while open_square_bracket >= 0 and close_square_bracket > 0:
|
||||||
|
# resolve brackets, this can be either the plain text or a key|value pair
|
||||||
|
key = stat[open_square_bracket + 1 : close_square_bracket]
|
||||||
|
|
||||||
|
if "|" in key: # key|value pair
|
||||||
|
key = key.split("|")[1] # use value
|
||||||
|
stat = stat[:open_square_bracket] + key + stat[close_square_bracket + 1 :]
|
||||||
|
|
||||||
|
open_square_bracket = stat.find("[")
|
||||||
|
close_square_bracket = stat.find("]")
|
||||||
|
|
||||||
|
pattern = re.compile(r"{\d+}")
|
||||||
|
for match in pattern.findall(stat):
|
||||||
|
stat = stat.replace(match, "#")
|
||||||
|
|
||||||
|
stat = stat.replace("{0:+d}", "+#")
|
||||||
|
|
||||||
|
if len(stat) == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if stat[0] == "{" and stat[1] == "}":
|
||||||
|
stat = "#" + stat[2:]
|
||||||
|
|
||||||
|
return stat
|
||||||
|
|
||||||
|
def parse_trade_ids(self):
|
||||||
|
for res in self.trade_stats["result"]:
|
||||||
|
for entry in res.get("entries"):
|
||||||
|
id = entry.get("id")
|
||||||
|
text = entry.get("text")
|
||||||
|
type = entry.get("type")
|
||||||
|
text = self.convert_stat_name(text)
|
||||||
|
|
||||||
|
if text not in self.stats_trade_ids:
|
||||||
|
self.stats_trade_ids[text] = {}
|
||||||
|
|
||||||
|
if type not in self.stats_trade_ids[text]:
|
||||||
|
self.stats_trade_ids[text][type] = []
|
||||||
|
|
||||||
|
self.stats_trade_ids[text][type].append(id)
|
||||||
|
|
||||||
|
def parse_mod(self, id, english):
|
||||||
|
matchers = []
|
||||||
|
ref = None
|
||||||
|
for lang in english:
|
||||||
|
lang = self.convert_stat_name(lang)
|
||||||
|
|
||||||
|
if lang is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
matcher = lang
|
||||||
|
# remove prefixes
|
||||||
|
if matcher[0] == "+":
|
||||||
|
matcher = matcher[1:]
|
||||||
|
|
||||||
|
has_negate = matcher.find("negate") > 0
|
||||||
|
|
||||||
|
if has_negate:
|
||||||
|
matcher = matcher[: matcher.find('"')].strip()
|
||||||
|
|
||||||
|
matchers.append({"string": matcher, "negate": has_negate})
|
||||||
|
|
||||||
|
if ref is None:
|
||||||
|
ref = lang
|
||||||
|
|
||||||
|
id = id.split(" ")
|
||||||
|
|
||||||
|
for a in id:
|
||||||
|
if a == "number_of_additional_arrows":
|
||||||
|
matchers.append(
|
||||||
|
{"string": "Bow Attacks fire # additional Arrows", "negate": False}
|
||||||
|
)
|
||||||
|
self.mod_translations[a] = {
|
||||||
|
"ref": ref,
|
||||||
|
"matchers": matchers,
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse_translation_file(self, file):
|
||||||
|
dir = f"{self.cwd}/descriptions/{file}"
|
||||||
|
print("Parsing", dir)
|
||||||
|
stats_translations = open(dir, encoding="utf-16").read().split("\n")
|
||||||
|
for i in range(0, len(stats_translations)):
|
||||||
|
line = stats_translations[i]
|
||||||
|
|
||||||
|
if line == "description":
|
||||||
|
# start of the translation block
|
||||||
|
id = (
|
||||||
|
stats_translations[i + 1].strip()[2:].replace('"', "")
|
||||||
|
) # skip first 2 characters
|
||||||
|
english = stats_translations[i + 3].strip() # skip first 2 characters
|
||||||
|
start = english.find('"')
|
||||||
|
end = english.rfind('"')
|
||||||
|
english = english[start + 1 : end]
|
||||||
|
|
||||||
|
# convert to array so we can add the negated option later on, if one exists
|
||||||
|
english = [english]
|
||||||
|
|
||||||
|
negate_english = stats_translations[i + 4].strip()
|
||||||
|
if "lang" not in negate_english and "negate" in negate_english:
|
||||||
|
# mod has a negated version
|
||||||
|
end = negate_english.find("negate")
|
||||||
|
negate_english = negate_english[
|
||||||
|
negate_english.find('"') + 1 : end + len("negate")
|
||||||
|
]
|
||||||
|
english.append(negate_english)
|
||||||
|
|
||||||
|
self.parse_mod(id, english)
|
||||||
|
|
||||||
|
def parse_mods(self):
|
||||||
|
for stat in self.stats_file:
|
||||||
|
id = stat.get("_index")
|
||||||
|
name = stat.get("Id")
|
||||||
|
self.stats[id] = name
|
||||||
|
|
||||||
|
# translations
|
||||||
|
for file in self.translation_files:
|
||||||
|
if os.path.isdir(f"{self.cwd}/descriptions/{file}"):
|
||||||
|
# traverse directories if it doesnt start with _
|
||||||
|
if not file.startswith("_"):
|
||||||
|
for _file in os.listdir(f"{self.cwd}/descriptions/{file}"):
|
||||||
|
self.parse_translation_file(f"{file}/{_file}")
|
||||||
|
elif ".csd" in file:
|
||||||
|
self.parse_translation_file(file)
|
||||||
|
|
||||||
|
for mod in self.mods_file:
|
||||||
|
id = mod.get("Id")
|
||||||
|
stats_key = mod.get("StatsKey1")
|
||||||
|
if stats_key is not None:
|
||||||
|
stats_id = self.stats.get(stats_key)
|
||||||
|
translation = self.mod_translations.get(stats_id)
|
||||||
|
if translation:
|
||||||
|
ref = translation.get("ref")
|
||||||
|
matchers = translation.get("matchers")
|
||||||
|
ids = self.stats_trade_ids.get(matchers[0].get("string"))
|
||||||
|
# if ref.lower() == "bow attacks fire an additional arrow":
|
||||||
|
# print("ID")
|
||||||
|
# print(f"stats_id: {stats_id}")
|
||||||
|
# print(f"matchers: {matchers}")
|
||||||
|
# print(f"ref: {ref}")
|
||||||
|
# print("break")
|
||||||
|
# print(f"mod: {mod}")
|
||||||
|
# print(f"stats_trade_ids: {stats_trade_ids}")
|
||||||
|
# print(f"ids: {ids}")
|
||||||
|
# print(f"translation: {translation}")
|
||||||
|
if ids is None and len(matchers) > 1:
|
||||||
|
ids = self.stats_trade_ids.get(matchers[1].get("string"))
|
||||||
|
if ids is None:
|
||||||
|
# print(
|
||||||
|
# "No trade ids found for",
|
||||||
|
# matchers[0].get("string"),
|
||||||
|
# "or",
|
||||||
|
# matchers[1].get("string"),
|
||||||
|
# )
|
||||||
|
self.matchers_no_trade_ids.append(matchers[0].get("string"))
|
||||||
|
self.matchers_no_trade_ids.append(matchers[1].get("string"))
|
||||||
|
elif ids is None:
|
||||||
|
# print("No trade ids found for", matchers[0].get("string"))
|
||||||
|
self.matchers_no_trade_ids.append(matchers[0].get("string"))
|
||||||
|
trade = {"ids": ids}
|
||||||
|
self.mods[id] = {
|
||||||
|
"ref": translation.get("ref"),
|
||||||
|
"better": 1,
|
||||||
|
"id": stats_id,
|
||||||
|
"matchers": translation.get("matchers"),
|
||||||
|
"trade": trade,
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse_categories(self):
|
||||||
|
# parse item categories
|
||||||
|
for cat in self.item_class_categories:
|
||||||
|
id = cat.get("_index")
|
||||||
|
if id is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
text = cat.get("Id")
|
||||||
|
self.parsed_item_class_categories[id] = text
|
||||||
|
|
||||||
|
for cat in self.item_classes:
|
||||||
|
id = cat.get("_index")
|
||||||
|
if id is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
text = cat.get("Id")
|
||||||
|
self.parsed_item_classes[id] = {
|
||||||
|
"name": text,
|
||||||
|
"short": self.parsed_item_class_categories.get(
|
||||||
|
cat.get("ItemClassCategory")
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse_items(self):
|
||||||
|
for entry in self.trade_items["result"]:
|
||||||
|
for item in entry.get("entries"):
|
||||||
|
name = item.get("name")
|
||||||
|
if name is None:
|
||||||
|
continue
|
||||||
|
text = item.get("text")
|
||||||
|
type = item.get("type")
|
||||||
|
# unique item
|
||||||
|
flags = item.get("flags")
|
||||||
|
|
||||||
|
self.unique_items.append(
|
||||||
|
{
|
||||||
|
"name": name,
|
||||||
|
"refName": name,
|
||||||
|
"namespace": "UNIQUE",
|
||||||
|
"unique": {"base": type},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# parse base items
|
||||||
|
for item in self.base_items:
|
||||||
|
id = item.get("_index")
|
||||||
|
if id is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
name = item.get("Name")
|
||||||
|
|
||||||
|
if len(name) == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
class_key = item.get("ItemClassesKey")
|
||||||
|
|
||||||
|
self.items[id] = {
|
||||||
|
"name": name,
|
||||||
|
"refName": name,
|
||||||
|
"namespace": "ITEM",
|
||||||
|
"class": class_key,
|
||||||
|
"dropLevel": item.get("DropLevel"),
|
||||||
|
"width": item.get("Width"),
|
||||||
|
"height": item.get("Height"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if class_key is not None:
|
||||||
|
class_info = self.parsed_item_classes.get(class_key).get("short")
|
||||||
|
# if class_info in ["Belt", "Ring", "Amulet"]:
|
||||||
|
if class_info is not None:
|
||||||
|
self.items[id].update({"craftable": {"category": class_info}})
|
||||||
|
|
||||||
|
# convert base items into gems
|
||||||
|
for gem in self.skill_gems:
|
||||||
|
id = gem.get("BaseItemTypesKey")
|
||||||
|
if id in self.items:
|
||||||
|
self.items[id].update(
|
||||||
|
{
|
||||||
|
"namespace": "GEM",
|
||||||
|
"gem": {"awakened": False, "transfigured": False},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# weapons and armor need the craftable tag ("craftable": "type (helmet, boots etc)")
|
||||||
|
# convert base items into weapons
|
||||||
|
for wpn in self.weapon_types:
|
||||||
|
id = wpn.get("BaseItemTypesKey")
|
||||||
|
|
||||||
|
if id in self.items:
|
||||||
|
class_key = self.items[id].get("class")
|
||||||
|
self.items[id].update(
|
||||||
|
{
|
||||||
|
"craftable": {
|
||||||
|
"category": self.parsed_item_classes.get(class_key).get(
|
||||||
|
"short"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# convert base items into armor types
|
||||||
|
# armour needs the armour tag ("armour": "ar": [min, max], "ev": [min, max], "es": [min, max])
|
||||||
|
# Changed since db only has once value for each stat
|
||||||
|
for armour in self.armour_types:
|
||||||
|
id = armour.get("BaseItemTypesKey")
|
||||||
|
|
||||||
|
ar = [armour.get("Armour"), armour.get("Armour")]
|
||||||
|
ev = [armour.get("Evasion"), armour.get("Evasion")]
|
||||||
|
es = [armour.get("EnergyShield"), armour.get("EnergyShield")]
|
||||||
|
|
||||||
|
armour = {}
|
||||||
|
|
||||||
|
if ar[1] > 1:
|
||||||
|
armour["ar"] = ar
|
||||||
|
|
||||||
|
if ev[1] > 1:
|
||||||
|
armour["ev"] = ev
|
||||||
|
|
||||||
|
if es[1] > 1:
|
||||||
|
armour["es"] = es
|
||||||
|
|
||||||
|
if id in self.items:
|
||||||
|
self.items[id].update({"armour": armour})
|
||||||
|
|
||||||
|
def parse_trade_exchange_items(self):
|
||||||
|
items_ids = {}
|
||||||
|
for id, item in self.items.items():
|
||||||
|
items_ids[item.get("name")] = id
|
||||||
|
|
||||||
|
for category in self.trade_exchange_items["result"]:
|
||||||
|
for entry in category.get("entries"):
|
||||||
|
item_name = entry.get("text")
|
||||||
|
|
||||||
|
if item_name not in items_ids:
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.items[items_ids[item_name]].update(
|
||||||
|
{
|
||||||
|
"tradeTag": entry.get("id"),
|
||||||
|
"icon": self.make_poe_cdn_url(entry.get("image")),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def resolve_item_classes(self):
|
||||||
|
for item_class in self.item_classes:
|
||||||
|
id = item_class.get("_index")
|
||||||
|
if id is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
name = item_class.get("Name")
|
||||||
|
item_class_category = item_class.get("ItemClassCategory")
|
||||||
|
|
||||||
|
if id in self.items:
|
||||||
|
self.items[id].update(
|
||||||
|
{
|
||||||
|
"class": name,
|
||||||
|
"category": self.parsed_item_classes.get(item_class_category),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def write_to_file(self):
|
||||||
|
f = open(f"{self.out_dir}/items.ndjson", "w", encoding="utf-8")
|
||||||
|
items_name = sorted(self.items.values(), key=lambda x: x.get("name"))
|
||||||
|
for item in items_name:
|
||||||
|
name = item.get("name")
|
||||||
|
namespace = item.get("namespace", "ITEM")
|
||||||
|
craftable = item.get("craftable", None)
|
||||||
|
gem = item.get("gem", None)
|
||||||
|
armour = item.get("armour", None)
|
||||||
|
width = item.get("width", None)
|
||||||
|
height = item.get("height", None)
|
||||||
|
tradeTag = item.get("tradeTag", None)
|
||||||
|
icon = item.get("icon", "%NOT_FOUND%")
|
||||||
|
|
||||||
|
out = {
|
||||||
|
"name": name,
|
||||||
|
"refName": name,
|
||||||
|
"namespace": namespace,
|
||||||
|
"icon": icon,
|
||||||
|
}
|
||||||
|
|
||||||
|
if tradeTag:
|
||||||
|
out.update({"tradeTag": tradeTag})
|
||||||
|
|
||||||
|
if craftable:
|
||||||
|
out.update({"craftable": craftable})
|
||||||
|
|
||||||
|
if armour:
|
||||||
|
out.update({"armour": armour})
|
||||||
|
|
||||||
|
if width:
|
||||||
|
out.update({"w": width})
|
||||||
|
|
||||||
|
if height:
|
||||||
|
out.update({"h": height})
|
||||||
|
|
||||||
|
if gem:
|
||||||
|
out.update({"gem": gem})
|
||||||
|
|
||||||
|
f.write(json.dumps(out) + "\n")
|
||||||
|
|
||||||
|
for item in self.unique_items:
|
||||||
|
f.write(json.dumps(item) + "\n")
|
||||||
|
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
# somehow not a thing? - possibly missing some data
|
||||||
|
self.mods["physical_local_damage_+%"] = {
|
||||||
|
"ref": "#% increased Physical Damage",
|
||||||
|
"better": 1,
|
||||||
|
"id": "physical_local_damage_+%",
|
||||||
|
"matchers": [{"string": "#% increased Physical Damage"}],
|
||||||
|
"trade": {
|
||||||
|
"ids": {
|
||||||
|
"explicit": ["explicit.stat_419810844"],
|
||||||
|
"fractured": ["fractured.stat_419810844"],
|
||||||
|
"rune": ["rune.stat_419810844"],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
seen = set()
|
||||||
|
m = open(f"{self.out_dir}/stats.ndjson", "w", encoding="utf-8")
|
||||||
|
for mod in self.mods.values():
|
||||||
|
id = mod.get("id")
|
||||||
|
|
||||||
|
if id in seen:
|
||||||
|
continue
|
||||||
|
|
||||||
|
m.write(json.dumps(mod) + "\n")
|
||||||
|
seen.add(id)
|
||||||
|
m.close()
|
||||||
|
|
||||||
|
with open(
|
||||||
|
f"{self.get_script_dir()}/pyDumps/{self.lang+'-out'}/items_dump.json",
|
||||||
|
"w",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as f:
|
||||||
|
f.write(json.dumps(self.items, indent=4))
|
||||||
|
|
||||||
|
with open(
|
||||||
|
f"{self.get_script_dir()}/pyDumps/{self.lang+'-out'}/mods_dump.json",
|
||||||
|
"w",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as f:
|
||||||
|
f.write(json.dumps(self.mods, indent=4))
|
||||||
|
|
||||||
|
with open(
|
||||||
|
f"{self.get_script_dir()}/pyDumps/{self.lang+'-out'}/matchers_no_trade_ids.json",
|
||||||
|
"w",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as f:
|
||||||
|
f.write(json.dumps(self.matchers_no_trade_ids, indent=4))
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.parse_trade_ids()
|
||||||
|
self.parse_mods()
|
||||||
|
self.parse_categories()
|
||||||
|
self.parse_items()
|
||||||
|
self.resolve_item_classes()
|
||||||
|
self.parse_trade_exchange_items()
|
||||||
|
self.write_to_file()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
Parser().run()
|
||||||
9
renderer/public/.DS_Store/vendor/client/parserRunner.py
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from parser import Parser
|
||||||
|
|
||||||
|
SUPPORTED_LANGUAGES = ["en", "ru"]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
for lang in SUPPORTED_LANGUAGES:
|
||||||
|
print(f"Generating {lang} tables")
|
||||||
|
parser = Parser(lang)
|
||||||
|
parser.run()
|
||||||
40053
renderer/public/.DS_Store/vendor/client/pyDumps/en-out/items_dump.json
vendored
Normal file
5812
renderer/public/.DS_Store/vendor/client/pyDumps/en-out/matchers_no_trade_ids.json
vendored
Normal file
204020
renderer/public/.DS_Store/vendor/client/pyDumps/en-out/mods_dump.json
vendored
Normal file
3059
renderer/public/.DS_Store/vendor/client/pyDumps/en/items.ndjson
vendored
Normal file
2910
renderer/public/.DS_Store/vendor/client/pyDumps/en/stats.ndjson
vendored
Normal file
3684
renderer/public/.DS_Store/vendor/client/tables/ArmourTypesOverride.json
vendored
Normal file
112
renderer/public/.DS_Store/vendor/client/tables/index.ts
vendored
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import * as fs from 'node:fs';
|
||||||
|
import * as path from 'node:path';
|
||||||
|
|
||||||
|
interface ArmourTypeRow {
|
||||||
|
BaseItemTypesKey: number;
|
||||||
|
Armour: number;
|
||||||
|
Evasion: number;
|
||||||
|
EnergyShield: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ArmourTypes(): ArmourTypeRow[] {
|
||||||
|
const data = fs.readFileSync(path.join(__dirname, 'ArmourTypes.json'), { encoding: 'utf-8' });
|
||||||
|
return JSON.parse(data) as ArmourTypeRow[];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface BaseItemTypeRow {
|
||||||
|
_index: number;
|
||||||
|
Id: string;
|
||||||
|
Width: number;
|
||||||
|
Height: number;
|
||||||
|
Name: string;
|
||||||
|
DropLevel: number;
|
||||||
|
Implicit_ModsKeys: string[];
|
||||||
|
ItemVisualIdentity: number;
|
||||||
|
IsCorrupted: boolean;
|
||||||
|
ItemClassesKey: string;
|
||||||
|
SiteVisibility: number;
|
||||||
|
TagsKeys: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function BaseItemTypes(lang: string = 'en'): BaseItemTypeRow[] {
|
||||||
|
const data = fs.readFileSync(path.join(__dirname, 'BaseItemTypes.json'), { encoding: 'utf-8' });
|
||||||
|
return JSON.parse(data) as BaseItemTypeRow[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ItemClassRow {
|
||||||
|
Id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ItemClasses(): ItemClassRow[] {
|
||||||
|
const data = fs.readFileSync(path.join(__dirname, 'ItemClasses.json'), { encoding: 'utf-8' });
|
||||||
|
return JSON.parse(data) as ItemClassRow[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ItemVisualIdentityRow {
|
||||||
|
_index: number;
|
||||||
|
Id: string;
|
||||||
|
DDSFile: string;
|
||||||
|
AOFile: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ItemVisualIdentity(): ItemVisualIdentityRow[] {
|
||||||
|
const data = fs.readFileSync(path.join(__dirname, 'ItemVisualIdentity.json'), { encoding: 'utf-8' });
|
||||||
|
return JSON.parse(data) as ItemVisualIdentityRow[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TagRow {
|
||||||
|
Id: string;
|
||||||
|
DisplayString: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Tags(): TagRow[] {
|
||||||
|
const data = fs.readFileSync(path.join(__dirname, 'Tags.json'), { encoding: 'utf-8' });
|
||||||
|
return JSON.parse(data) as TagRow[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UniqueStashLayoutRow {
|
||||||
|
WordsKey: number;
|
||||||
|
ShowIfEmptyChallengeLeague: boolean;
|
||||||
|
RenamedVersion: number;
|
||||||
|
UniqueStashTypesKey: number;
|
||||||
|
ItemVisualIdentityKey: number;
|
||||||
|
ShowIfEmptyStandard: boolean;
|
||||||
|
IsAlternateArt: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function UniquesStashLayout(): UniqueStashLayoutRow[] {
|
||||||
|
const data = fs.readFileSync(path.join(__dirname, 'UniquesStashLayout.json'), { encoding: 'utf-8' });
|
||||||
|
return JSON.parse(data) as UniqueStashLayoutRow[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WordRow {
|
||||||
|
_index: number;
|
||||||
|
Wordlist: number;
|
||||||
|
Text: string;
|
||||||
|
SpawnWeight_Tags: number[];
|
||||||
|
SpawnWeight_Values: number[];
|
||||||
|
Text2: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Words(lang: string = 'en'): WordRow[] {
|
||||||
|
const data = fs.readFileSync(path.join(__dirname, 'Words.json'), { encoding: 'utf-8' });
|
||||||
|
return JSON.parse(data) as WordRow[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StatsRow {
|
||||||
|
Id: string;
|
||||||
|
IsLocal: boolean;
|
||||||
|
IsWeaponLocal: boolean;
|
||||||
|
Semantics: number;
|
||||||
|
Text: string;
|
||||||
|
IsVirtual: boolean;
|
||||||
|
HASH32: number;
|
||||||
|
BelongsActiveSkillsKey: string[];
|
||||||
|
IsScalable: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Stats(): StatsRow[] {
|
||||||
|
const data = fs.readFileSync(path.join(__dirname, 'Stats.json'), { encoding: 'utf-8' });
|
||||||
|
return JSON.parse(data) as StatsRow[];
|
||||||
|
}
|
||||||
0
renderer/public/.DS_Store/vendor/json-api/cmn-Hant/.gitkeep
vendored
Normal file
0
renderer/public/.DS_Store/vendor/json-api/en/.gitkeep
vendored
Normal file
0
renderer/public/.DS_Store/vendor/json-api/ko/.gitkeep
vendored
Normal file
0
renderer/public/.DS_Store/vendor/json-api/ru/.gitkeep
vendored
Normal file
86
renderer/public/.DS_Store/vendor/pseudo-stats/add-to-new.py
vendored
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def get_script_dir():
|
||||||
|
"""Returns the directory where the script is located."""
|
||||||
|
return os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
# List of localization codes
|
||||||
|
localizations = ["en", "ru", "ko", "cmn-Hant"]
|
||||||
|
|
||||||
|
|
||||||
|
def process_filtered_pseudo_stats(loc):
|
||||||
|
filtered_file_path = f"{get_script_dir()}/{loc}/pseudo_stats.ndjson"
|
||||||
|
stats_file_path = f"{get_script_dir()}/../../data/{loc}/stats.ndjson"
|
||||||
|
output_file_path = f"{get_script_dir()}/../../data/{loc}/updated_stats.ndjson"
|
||||||
|
|
||||||
|
# Load all stats at the start to avoid repeated loading
|
||||||
|
with open(stats_file_path, "r", encoding="utf-8") as stats_file:
|
||||||
|
original_stats_lines = [json.loads(line) for line in stats_file]
|
||||||
|
|
||||||
|
updated_lines = []
|
||||||
|
matched_keys = set() # To track keys that have been updated
|
||||||
|
|
||||||
|
with open(filtered_file_path, "r", encoding="utf-8") as filtered_file:
|
||||||
|
for line in filtered_file:
|
||||||
|
try:
|
||||||
|
pseudo_object = json.loads(line)
|
||||||
|
# Check for non-pseudo keys
|
||||||
|
if "trade" in pseudo_object and "ids" in pseudo_object["trade"]:
|
||||||
|
non_pseudo_found = any(
|
||||||
|
key in pseudo_object["trade"]["ids"]
|
||||||
|
for key in ["explicit", "implicit", "enchant"]
|
||||||
|
)
|
||||||
|
|
||||||
|
if non_pseudo_found:
|
||||||
|
# Search for the corresponding stat
|
||||||
|
for stats_object in original_stats_lines:
|
||||||
|
# Check if the trade.ids matches with non-pseudo keys
|
||||||
|
for key in ["explicit", "implicit", "enchant"]:
|
||||||
|
if key in pseudo_object["trade"]["ids"]:
|
||||||
|
value_to_find = pseudo_object["trade"]["ids"][key]
|
||||||
|
# Ensure stats_object exists and has 'trade' and 'ids' before accessing
|
||||||
|
if (
|
||||||
|
stats_object.get("trade") is not None
|
||||||
|
and stats_object["trade"].get("ids") is not None
|
||||||
|
and stats_object["trade"]["ids"].get(key)
|
||||||
|
== value_to_find
|
||||||
|
):
|
||||||
|
# Cut the line and add the pseudo value
|
||||||
|
new_stats_object = (
|
||||||
|
stats_object.copy()
|
||||||
|
) # Use copy to avoid modifying original
|
||||||
|
new_stats_object["trade"]["ids"]["pseudo"] = (
|
||||||
|
pseudo_object["trade"]["ids"].get("pseudo")
|
||||||
|
)
|
||||||
|
updated_lines.append(new_stats_object)
|
||||||
|
matched_keys.add(
|
||||||
|
json.dumps(stats_object, ensure_ascii=False)
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
|
# If not matched, add the pseudo object as is
|
||||||
|
else:
|
||||||
|
updated_lines.append(pseudo_object)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
print(f"Error parsing JSON from filtered file: {line}")
|
||||||
|
|
||||||
|
# Write updated lines and remaining original stats to a new stats file
|
||||||
|
with open(output_file_path, "w", encoding="utf-8") as output_file:
|
||||||
|
# Write new lines at the top
|
||||||
|
for updated_line in updated_lines:
|
||||||
|
output_file.write(json.dumps(updated_line, ensure_ascii=False) + "\n")
|
||||||
|
|
||||||
|
# Write the original lines that have not been matched
|
||||||
|
for original_line in original_stats_lines:
|
||||||
|
if json.dumps(original_line, ensure_ascii=False) not in matched_keys:
|
||||||
|
output_file.write(json.dumps(original_line, ensure_ascii=False) + "\n")
|
||||||
|
|
||||||
|
print(f"Updated stats written to {output_file_path} for {loc}.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
for loc in localizations:
|
||||||
|
process_filtered_pseudo_stats(loc)
|
||||||
292
renderer/public/.DS_Store/vendor/pseudo-stats/all-pseudo.ndjson
vendored
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
{"ref": "# Crafted Modifiers", "better": 1, "matchers": [{"string": "# Crafted Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_crafted_mods"]}}}
|
||||||
|
{"ref": "# Crafted Prefix Modifiers", "better": 1, "matchers": [{"string": "# Crafted Prefix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_crafted_prefix_mods"]}}}
|
||||||
|
{"ref": "# Crafted Suffix Modifiers", "better": 1, "matchers": [{"string": "# Crafted Suffix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_crafted_suffix_mods"]}}}
|
||||||
|
{"ref": "# Empty Modifiers", "better": 1, "matchers": [{"string": "# Empty Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_empty_affix_mods"]}}}
|
||||||
|
{"ref": "# Empty Prefix Modifiers", "better": 1, "matchers": [{"string": "# Empty Prefix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_empty_prefix_mods"]}}}
|
||||||
|
{"ref": "# Empty Suffix Modifiers", "better": 1, "matchers": [{"string": "# Empty Suffix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_empty_suffix_mods"]}}}
|
||||||
|
{"ref": "# Enchant Modifiers", "better": 1, "matchers": [{"string": "# Enchant Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_enchant_mods"]}}}
|
||||||
|
{"ref": "# Fractured Modifiers", "better": 1, "matchers": [{"string": "# Fractured Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_fractured_mods"]}}}
|
||||||
|
{"ref": "# Implicit Modifiers", "better": 1, "matchers": [{"string": "# Implicit Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_implicit_mods"]}}}
|
||||||
|
{"ref": "# Life Regenerated per Second", "better": 1, "matchers": [{"string": "# Life Regenerated per Second "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_life_regen"]}}}
|
||||||
|
{"ref": "# Modifiers", "better": 1, "matchers": [{"string": "# Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_affix_mods"]}}}
|
||||||
|
{"ref": "# Notable Passive Skills", "better": 1, "matchers": [{"string": "# Notable Passive Skills "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_notable_passive_skills"]}}}
|
||||||
|
{"ref": "# Prefix Modifiers", "better": 1, "matchers": [{"string": "# Prefix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_prefix_mods"]}}}
|
||||||
|
{"ref": "# Suffix Modifiers", "better": 1, "matchers": [{"string": "# Suffix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_suffix_mods"]}}}
|
||||||
|
{"ref": "# total Elemental Resistances", "better": 1, "matchers": [{"string": "# total Elemental Resistances "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_count_elemental_resistances"]}}}
|
||||||
|
{"ref": "# total Resistances", "better": 1, "matchers": [{"string": "# total Resistances "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_count_resistances"]}}}
|
||||||
|
{"ref": "#% Base Defence Percentile", "better": 1, "matchers": [{"string": "#% Base Defence Percentile "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_base_defence_percentile"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Atlas Memories", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Atlas Memories "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_memory_line"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Conqueror Maps", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Conqueror Maps "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_conqueror_map"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Elder Maps", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Elder Maps "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_elder_map"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Maven Invitations", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Maven Invitations "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_maven_invitation"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Scarabs", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Scarabs "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_scarab"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Shaper Maps", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Shaper Maps "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_shaper_map"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Unique Maps", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Unique Maps "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_unique_map"]}}}
|
||||||
|
{"ref": "#% increased Burning Damage", "better": 1, "matchers": [{"string": "#% increased Burning Damage"}, {"string": "#% reduced Burning Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_burning_damage"], "explicit": ["explicit.stat_1175385867"], "implicit": ["implicit.stat_1175385867"], "fractured": ["fractured.stat_1175385867"]}}}
|
||||||
|
{"ref": "#% increased Cold Damage", "better": 1, "matchers": [{"string": "#% increased Cold Damage"}, {"string": "#% reduced Cold Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_damage"], "explicit": ["explicit.stat_3291658075"], "implicit": ["implicit.stat_3291658075"], "fractured": ["fractured.stat_3291658075"], "scourge": ["scourge.stat_3291658075"], "crafted": ["crafted.stat_3291658075"]}}}
|
||||||
|
{"ref": "#% increased Cold Damage with Attack Skills", "better": 1, "matchers": [{"string": "#% increased Cold Damage with Attack Skills"}, {"string": "#% reduced Cold Damage with Attack Skills", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_damage_with_attack_skills"], "explicit": ["explicit.stat_860668586"], "implicit": ["implicit.stat_860668586"]}}}
|
||||||
|
{"ref": "#% increased Cold Spell Damage", "better": 1, "matchers": [{"string": "#% increased Cold Spell Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Elemental Damage", "better": 1, "matchers": [{"string": "#% increased Elemental Damage"}, {"string": "Has #% increased Elemental Damage"}, {"string": "#% reduced Elemental Damage", "negate": true}, {"string": "Has #% reduced Elemental Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_elemental_damage"], "explicit": ["explicit.stat_3141070085"], "implicit": ["implicit.stat_3141070085"], "fractured": ["fractured.stat_3141070085"], "enchant": ["enchant.stat_692420067"], "scourge": ["scourge.stat_3141070085"]}}}
|
||||||
|
{"ref": "#% increased Elemental Damage with Attack Skills", "better": 1, "matchers": [{"string": "#% increased Elemental Damage with Attack Skills"}, {"string": "#% reduced Elemental Damage with Attack Skills", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_elemental_damage_with_attack_skills"], "explicit": ["explicit.stat_387439868"], "implicit": ["implicit.stat_387439868"], "fractured": ["fractured.stat_387439868"], "scourge": ["scourge.stat_387439868"], "crafted": ["crafted.stat_387439868"]}}}
|
||||||
|
{"ref": "#% increased Fire Damage", "better": 1, "matchers": [{"string": "#% increased Fire Damage"}, {"string": "#% reduced Fire Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_damage"], "explicit": ["explicit.stat_3962278098"], "implicit": ["implicit.stat_3962278098"], "fractured": ["fractured.stat_3962278098"], "scourge": ["scourge.stat_3962278098"], "crafted": ["crafted.stat_3962278098"]}}}
|
||||||
|
{"ref": "#% increased Fire Damage with Attack Skills", "better": 1, "matchers": [{"string": "#% increased Fire Damage with Attack Skills"}, {"string": "#% reduced Fire Damage with Attack Skills", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_damage_with_attack_skills"], "implicit": ["implicit.stat_2468413380"]}}}
|
||||||
|
{"ref": "#% increased Fire Spell Damage", "better": 1, "matchers": [{"string": "#% increased Fire Spell Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Lightning Damage", "better": 1, "matchers": [{"string": "#% increased Lightning Damage"}, {"string": "#% reduced Lightning Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_damage"], "explicit": ["explicit.stat_2231156303"], "implicit": ["implicit.stat_2231156303"], "fractured": ["fractured.stat_2231156303"], "scourge": ["scourge.stat_2231156303"], "crafted": ["crafted.stat_2231156303"]}}}
|
||||||
|
{"ref": "#% increased Lightning Damage with Attack Skills", "better": 1, "matchers": [{"string": "#% increased Lightning Damage with Attack Skills"}, {"string": "#% reduced Lightning Damage with Attack Skills", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_damage_with_attack_skills"], "explicit": ["explicit.stat_4208907162"], "implicit": ["implicit.stat_4208907162"]}}}
|
||||||
|
{"ref": "#% increased Lightning Spell Damage", "better": 1, "matchers": [{"string": "#% increased Lightning Spell Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Mana Regeneration Rate", "better": 1, "matchers": [{"string": "#% increased Mana Regeneration Rate"}, {"string": "#% reduced Mana Regeneration Rate", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_mana_regen"], "explicit": ["explicit.stat_789117908"], "implicit": ["implicit.stat_789117908"], "fractured": ["fractured.stat_789117908"], "scourge": ["scourge.stat_789117908"], "crafted": ["crafted.stat_789117908"]}}}
|
||||||
|
{"ref": "#% increased Movement Speed", "better": 1, "matchers": [{"string": "#% increased Movement Speed"}, {"string": "#% reduced Movement Speed", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_movement_speed"], "explicit": ["explicit.stat_2250533757"], "implicit": ["implicit.stat_2250533757"], "fractured": ["fractured.stat_2250533757"], "enchant": ["enchant.stat_2250533757"], "scourge": ["scourge.stat_2250533757"], "crafted": ["crafted.stat_2250533757"]}}}
|
||||||
|
{"ref": "#% increased Rarity of Items found", "better": 1, "matchers": [{"string": "#% increased Rarity of Items found"}, {"string": "#% reduced Rarity of Items found", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_rarity"], "explicit": ["explicit.stat_3917489142"], "implicit": ["implicit.stat_3917489142"], "fractured": ["fractured.stat_3917489142"], "scourge": ["scourge.stat_3917489142"], "crafted": ["crafted.stat_3917489142"]}}}
|
||||||
|
{"ref": "#% increased Spell Damage", "better": 1, "matchers": [{"string": "#% increased Spell Damage"}, {"string": "#% reduced Spell Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_spell_damage"], "explicit": ["explicit.stat_2974417149"], "implicit": ["implicit.stat_2974417149"], "fractured": ["fractured.stat_2974417149"], "enchant": ["enchant.stat_2974417149"], "scourge": ["scourge.stat_2974417149"], "crafted": ["crafted.stat_2974417149"]}}}
|
||||||
|
{"ref": "#% of Life Regenerated per Second", "better": 1, "matchers": [{"string": "#% of Life Regenerated per Second "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_percent_life_regen"]}}}
|
||||||
|
{"ref": "#% of Physical Attack Damage Leeched as Life", "dp": true, "better": 1, "matchers": [{"string": "#% of Physical Attack Damage Leeched as Life"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_physical_attack_damage_leeched_as_life"], "explicit": ["explicit.stat_3593843976", "explicit.stat_55876295"], "implicit": ["implicit.stat_3593843976", "implicit.stat_55876295"], "fractured": ["fractured.stat_3593843976", "fractured.stat_55876295"], "scourge": ["scourge.stat_3593843976"], "crafted": ["crafted.stat_3593843976", "crafted.stat_55876295"]}}}
|
||||||
|
{"ref": "#% of Physical Attack Damage Leeched as Mana", "dp": true, "better": 1, "matchers": [{"string": "#% of Physical Attack Damage Leeched as Mana"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_physical_attack_damage_leeched_as_mana"], "explicit": ["explicit.stat_3237948413", "explicit.stat_669069897"], "implicit": ["implicit.stat_3237948413", "implicit.stat_669069897"], "fractured": ["fractured.stat_3237948413", "fractured.stat_669069897"], "enchant": ["enchant.stat_669069897"], "scourge": ["scourge.stat_3237948413"], "crafted": ["crafted.stat_3237948413", "crafted.stat_669069897"]}}}
|
||||||
|
{"ref": "#% total increased maximum Energy Shield", "better": 1, "matchers": [{"string": "#% total increased maximum Energy Shield "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_energy_shield"]}}}
|
||||||
|
{"ref": "#% total increased Physical Damage", "better": 1, "matchers": [{"string": "#% total increased Physical Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_physical_damage"]}}}
|
||||||
|
{"ref": "+# total maximum Energy Shield", "better": 1, "matchers": [{"string": "+# total maximum Energy Shield "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_energy_shield"]}}}
|
||||||
|
{"ref": "+# total maximum Life", "better": 1, "matchers": [{"string": "+# total maximum Life "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_life"]}}}
|
||||||
|
{"ref": "+# total maximum Mana", "better": 1, "matchers": [{"string": "+# total maximum Mana "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_mana"]}}}
|
||||||
|
{"ref": "+# total to all Attributes", "better": 1, "matchers": [{"string": "+# total to all Attributes "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_all_attributes"]}}}
|
||||||
|
{"ref": "+# total to Dexterity", "better": 1, "matchers": [{"string": "+# total to Dexterity "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_dexterity"]}}}
|
||||||
|
{"ref": "+# total to Intelligence", "better": 1, "matchers": [{"string": "+# total to Intelligence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_intelligence"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Aura Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Aura Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_aura_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Bow Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Bow Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_bow_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Chaos Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Chaos Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_chaos_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Cold Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Cold Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_cold_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Curse Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Curse Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_curse_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Dexterity Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Dexterity Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_dexterity_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Elemental Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Elemental Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_elemental_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Fire Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Fire Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_fire_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Golem Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Golem Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_golem_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Intelligence Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Intelligence Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_intelligence_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Lightning Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Lightning Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_lightning_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Melee Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Melee Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_melee_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Minion Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Minion Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_minion_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Movement Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Movement Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_movement_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Projectile Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Projectile Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_projectile_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Skill Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Skill Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_skill_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Spell Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Spell Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_spell_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Strength Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Strength Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_strength_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Support Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Support Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_support_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Vaal Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Vaal Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_vaal_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Warcry Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Warcry Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_warcry_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Strength", "better": 1, "matchers": [{"string": "+# total to Strength "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_strength"]}}}
|
||||||
|
{"ref": "+#% Global Critical Strike Chance", "better": 1, "matchers": [{"string": "+#% Global Critical Strike Chance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_global_critical_strike_chance"]}}}
|
||||||
|
{"ref": "+#% Global Critical Strike Multiplier", "better": 1, "matchers": [{"string": "+#% Global Critical Strike Multiplier "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_global_critical_strike_multiplier"]}}}
|
||||||
|
{"ref": "+#% total Attack Speed", "better": 1, "matchers": [{"string": "+#% total Attack Speed "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_attack_speed"]}}}
|
||||||
|
{"ref": "+#% total Cast Speed", "better": 1, "matchers": [{"string": "+#% total Cast Speed "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_cast_speed"]}}}
|
||||||
|
{"ref": "+#% total Critical Strike Chance for Spells", "better": 1, "matchers": [{"string": "+#% total Critical Strike Chance for Spells "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_critical_strike_chance_for_spells"]}}}
|
||||||
|
{"ref": "+#% total Elemental Resistance", "better": 1, "matchers": [{"string": "+#% total Elemental Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_elemental_resistance"]}}}
|
||||||
|
{"ref": "+#% total Resistance", "better": 1, "matchers": [{"string": "+#% total Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_resistance"]}}}
|
||||||
|
{"ref": "+#% total to all Elemental Resistances", "better": 1, "matchers": [{"string": "+#% total to all Elemental Resistances "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_all_elemental_resistances"]}}}
|
||||||
|
{"ref": "+#% total to Chaos Resistance", "better": 1, "matchers": [{"string": "+#% total to Chaos Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_chaos_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Cold Resistance", "better": 1, "matchers": [{"string": "+#% total to Cold Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_cold_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Fire Resistance", "better": 1, "matchers": [{"string": "+#% total to Fire Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_fire_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Lightning Resistance", "better": 1, "matchers": [{"string": "+#% total to Lightning Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_lightning_resistance"]}}}
|
||||||
|
{"ref": "Adds # to # Chaos Damage", "better": 1, "matchers": [{"string": "Adds # to # Chaos Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_chaos_damage"], "explicit": ["explicit.stat_2223678961", "explicit.stat_3531280422"], "implicit": ["implicit.stat_2223678961", "implicit.stat_3531280422"], "fractured": ["fractured.stat_2223678961"], "enchant": ["enchant.stat_2223678961"], "scourge": ["scourge.stat_2223678961"]}}}
|
||||||
|
{"ref": "Adds # to # Chaos Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Chaos Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_chaos_damage_to_attacks"], "explicit": ["explicit.stat_674553446"], "implicit": ["implicit.stat_674553446"], "fractured": ["fractured.stat_674553446"], "crafted": ["crafted.stat_674553446"]}}}
|
||||||
|
{"ref": "Adds # to # Chaos Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Chaos Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_chaos_damage_to_spells"], "explicit": ["explicit.stat_2300399854"], "implicit": ["implicit.stat_2300399854"], "fractured": ["fractured.stat_2300399854"]}}}
|
||||||
|
{"ref": "Adds # to # Cold Damage", "better": 1, "matchers": [{"string": "Adds # to # Cold Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_cold_damage"], "explicit": ["explicit.stat_1037193709", "explicit.stat_2387423236"], "implicit": ["implicit.stat_1037193709", "implicit.stat_2387423236"], "fractured": ["fractured.stat_1037193709", "fractured.stat_2387423236"], "enchant": ["enchant.stat_1037193709"], "scourge": ["scourge.stat_1037193709"], "crafted": ["crafted.stat_1037193709", "crafted.stat_2387423236"]}}}
|
||||||
|
{"ref": "Adds # to # Cold Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Cold Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_cold_damage_to_attacks"], "explicit": ["explicit.stat_4067062424"], "implicit": ["implicit.stat_4067062424"], "fractured": ["fractured.stat_4067062424"], "crafted": ["crafted.stat_4067062424"]}}}
|
||||||
|
{"ref": "Adds # to # Cold Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Cold Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_cold_damage_to_spells"], "explicit": ["explicit.stat_2469416729"], "implicit": ["implicit.stat_2469416729"], "fractured": ["fractured.stat_2469416729"], "scourge": ["scourge.stat_2469416729"], "crafted": ["crafted.stat_2469416729"]}}}
|
||||||
|
{"ref": "Adds # to # Damage", "better": 1, "matchers": [{"string": "Adds # to # Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_damage"]}}}
|
||||||
|
{"ref": "Adds # to # Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Damage to Attacks "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_damage_to_attacks"]}}}
|
||||||
|
{"ref": "Adds # to # Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Damage to Spells "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_damage_to_spells"]}}}
|
||||||
|
{"ref": "Adds # to # Elemental Damage", "better": 1, "matchers": [{"string": "Adds # to # Elemental Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_elemental_damage"]}}}
|
||||||
|
{"ref": "Adds # to # Elemental Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Elemental Damage to Attacks "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_elemental_damage_to_attacks"]}}}
|
||||||
|
{"ref": "Adds # to # Elemental Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Elemental Damage to Spells "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_elemental_damage_to_spells"]}}}
|
||||||
|
{"ref": "Adds # to # Fire Damage", "better": 1, "matchers": [{"string": "Adds # to # Fire Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_fire_damage"], "explicit": ["explicit.stat_321077055", "explicit.stat_709508406"], "implicit": ["implicit.stat_321077055", "implicit.stat_709508406"], "fractured": ["fractured.stat_321077055", "fractured.stat_709508406"], "enchant": ["enchant.stat_709508406"], "scourge": ["scourge.stat_709508406"], "crafted": ["crafted.stat_321077055", "crafted.stat_709508406"]}}}
|
||||||
|
{"ref": "Adds # to # Fire Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Fire Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_fire_damage_to_attacks"], "explicit": ["explicit.stat_1573130764"], "implicit": ["implicit.stat_1573130764"], "fractured": ["fractured.stat_1573130764"], "crafted": ["crafted.stat_1573130764"]}}}
|
||||||
|
{"ref": "Adds # to # Fire Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Fire Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_fire_damage_to_spells"], "explicit": ["explicit.stat_1133016593"], "implicit": ["implicit.stat_1133016593"], "fractured": ["fractured.stat_1133016593"], "scourge": ["scourge.stat_1133016593"], "crafted": ["crafted.stat_1133016593"]}}}
|
||||||
|
{"ref": "Adds # to # Lightning Damage", "better": 1, "matchers": [{"string": "Adds # to # Lightning Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_lightning_damage"], "explicit": ["explicit.stat_1334060246", "explicit.stat_3336890334"], "implicit": ["implicit.stat_1334060246", "implicit.stat_3336890334"], "fractured": ["fractured.stat_1334060246", "fractured.stat_3336890334"], "enchant": ["enchant.stat_3336890334"], "scourge": ["scourge.stat_3336890334"], "crafted": ["crafted.stat_1334060246", "crafted.stat_3336890334"]}}}
|
||||||
|
{"ref": "Adds # to # Lightning Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Lightning Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_lightning_damage_to_attacks"], "explicit": ["explicit.stat_1754445556"], "implicit": ["implicit.stat_1754445556"], "fractured": ["fractured.stat_1754445556"], "crafted": ["crafted.stat_1754445556"]}}}
|
||||||
|
{"ref": "Adds # to # Lightning Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Lightning Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_lightning_damage_to_spells"], "explicit": ["explicit.stat_2831165374"], "implicit": ["implicit.stat_2831165374"], "fractured": ["fractured.stat_2831165374"], "scourge": ["scourge.stat_2831165374"], "crafted": ["crafted.stat_2831165374"]}}}
|
||||||
|
{"ref": "Adds # to # Physical Damage", "better": 1, "matchers": [{"string": "Adds # to # Physical Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_physical_damage"], "explicit": ["explicit.stat_1940865751", "explicit.stat_960081730"], "implicit": ["implicit.stat_1940865751"], "fractured": ["fractured.stat_1940865751", "fractured.stat_960081730"], "scourge": ["scourge.stat_1940865751"], "crafted": ["crafted.stat_1940865751"]}}}
|
||||||
|
{"ref": "Adds # to # Physical Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Physical Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_physical_damage_to_attacks"], "explicit": ["explicit.stat_3032590688"], "implicit": ["implicit.stat_3032590688"], "fractured": ["fractured.stat_3032590688"], "crafted": ["crafted.stat_3032590688"]}}}
|
||||||
|
{"ref": "Adds # to # Physical Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Physical Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_physical_damage_to_spells"], "explicit": ["explicit.stat_2435536961"], "implicit": ["implicit.stat_2435536961"], "fractured": ["fractured.stat_2435536961"], "scourge": ["scourge.stat_2435536961"]}}}
|
||||||
|
{"ref": "Has # Influences", "better": 1, "matchers": [{"string": "Has # Influences "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_influence_count"]}}}
|
||||||
|
{"ref": "Has Crusader Influence", "better": 1, "matchers": [{"string": "Has Crusader Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_crusader_influence"]}}}
|
||||||
|
{"ref": "Has Elder Influence", "better": 1, "matchers": [{"string": "Has Elder Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_elder_influence"]}}}
|
||||||
|
{"ref": "Has Hunter Influence", "better": 1, "matchers": [{"string": "Has Hunter Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_hunter_influence"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Battleground Graves", "better": 1, "matchers": [{"string": "Has Logbook Area: Battleground Graves "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_battleground_graves"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Bluffs", "better": 1, "matchers": [{"string": "Has Logbook Area: Bluffs "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_bluffs"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Cemetery", "better": 1, "matchers": [{"string": "Has Logbook Area: Cemetery "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_cemetery"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Desert Ruins", "better": 1, "matchers": [{"string": "Has Logbook Area: Desert Ruins "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_desert_ruins"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Dried Riverbed", "better": 1, "matchers": [{"string": "Has Logbook Area: Dried Riverbed "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_dried_riverbed"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Forest Ruins", "better": 1, "matchers": [{"string": "Has Logbook Area: Forest Ruins "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_forest_ruins"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Karui Wargraves", "better": 1, "matchers": [{"string": "Has Logbook Area: Karui Wargraves "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_karui_wargraves"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Mountainside", "better": 1, "matchers": [{"string": "Has Logbook Area: Mountainside "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_mountainside"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Rotting Temple", "better": 1, "matchers": [{"string": "Has Logbook Area: Rotting Temple "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_rotting_temple"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Sarn Slums", "better": 1, "matchers": [{"string": "Has Logbook Area: Sarn Slums "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_sarn_slums"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Scrublands", "better": 1, "matchers": [{"string": "Has Logbook Area: Scrublands "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_scrublands"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Shipwreck Reef", "better": 1, "matchers": [{"string": "Has Logbook Area: Shipwreck Reef "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_shipwreck_reef"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Utzaal Outskirts", "better": 1, "matchers": [{"string": "Has Logbook Area: Utzaal Outskirts "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_utzaal_outskirts"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Vaal Temple", "better": 1, "matchers": [{"string": "Has Logbook Area: Vaal Temple "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_vaal_temple"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Volcanic Island", "better": 1, "matchers": [{"string": "Has Logbook Area: Volcanic Island "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_volcano"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Black Scythe Mercenaries", "better": 0, "matchers": [{"string": "Black Scythe Mercenaries"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_mercenaries"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Druids of the Broken Circle", "better": 0, "matchers": [{"string": "Druids of the Broken Circle"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_druids"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Knights of the Sun", "better": 0, "matchers": [{"string": "Knights of the Sun"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_knights"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Order of the Chalice", "better": 0, "matchers": [{"string": "Order of the Chalice"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_order"]}}}
|
||||||
|
{"ref": "Has Redeemer Influence", "better": 1, "matchers": [{"string": "Has Redeemer Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_redeemer_influence"]}}}
|
||||||
|
{"ref": "Has Room: Antechamber", "better": 0, "matchers": [{"string": "Antechamber"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_antechamber"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Apex of Ascension (Tier 3)", "better": 0, "matchers": [{"string": "Apex of Ascension (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_sacrifice_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Apex of Atzoatl", "better": 0, "matchers": [{"string": "Apex of Atzoatl"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_apex"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Arena of Valour (Tier 2)", "better": 0, "matchers": [{"string": "Arena of Valour (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_weapon_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Armourer's Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Armourer's Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_armour_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Armoury (Tier 2)", "better": 0, "matchers": [{"string": "Armoury (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_armour_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Atlas of Worlds (Tier 3)", "better": 0, "matchers": [{"string": "Atlas of Worlds (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cartography_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Automaton Lab (Tier 2)", "better": 0, "matchers": [{"string": "Automaton Lab (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_minions_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Banquet Hall", "better": 0, "matchers": [{"string": "Banquet Hall"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_banquet_hall"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Barracks (Tier 2)", "better": 0, "matchers": [{"string": "Barracks (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breeding_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Breach Containment Chamber (Tier 2)", "better": 0, "matchers": [{"string": "Breach Containment Chamber (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breach_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Catalyst of Corruption (Tier 2)", "better": 0, "matchers": [{"string": "Catalyst of Corruption (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_corruption_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Cellar", "better": 0, "matchers": [{"string": "Cellar"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cellar"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Chamber of Iron (Tier 3)", "better": 0, "matchers": [{"string": "Chamber of Iron (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_armour_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Chasm", "better": 0, "matchers": [{"string": "Chasm"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chasm_room"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Cloister", "better": 0, "matchers": [{"string": "Cloister"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cloister"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Conduit of Lightning (Tier 3)", "better": 0, "matchers": [{"string": "Conduit of Lightning (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_lightning_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Corruption Chamber (Tier 1)", "better": 0, "matchers": [{"string": "Corruption Chamber (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_corruption_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Court of Sealed Death (Tier 3)", "better": 0, "matchers": [{"string": "Court of Sealed Death (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_strongbox_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Crucible of Flame (Tier 3)", "better": 0, "matchers": [{"string": "Crucible of Flame (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_fire_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Cultivar Chamber (Tier 2)", "better": 0, "matchers": [{"string": "Cultivar Chamber (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_poison_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Defense Research Lab (Tier 3)", "better": 0, "matchers": [{"string": "Defense Research Lab (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trap_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Demolition Lab (Tier 2)", "better": 0, "matchers": [{"string": "Demolition Lab (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_explosives_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Department of Thaumaturgy (Tier 2)", "better": 0, "matchers": [{"string": "Department of Thaumaturgy (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_gem_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Doryani's Institute (Tier 3)", "better": 0, "matchers": [{"string": "Doryani's Institute (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_gem_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Engineering Department (Tier 2)", "better": 0, "matchers": [{"string": "Engineering Department (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_workshop_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Explosives Room (Tier 1)", "better": 0, "matchers": [{"string": "Explosives Room (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_explosives_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Factory (Tier 3)", "better": 0, "matchers": [{"string": "Factory (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_workshop_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Flame Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Flame Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_fire_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Gemcutter's Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Gemcutter's Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_gem_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Glittering Halls (Tier 3)", "better": 0, "matchers": [{"string": "Glittering Halls (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trinket_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Guardhouse (Tier 1)", "better": 0, "matchers": [{"string": "Guardhouse (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breeding_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Champions (Tier 3)", "better": 0, "matchers": [{"string": "Hall of Champions (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_weapon_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Heroes (Tier 2)", "better": 0, "matchers": [{"string": "Hall of Heroes (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_legion_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Legends (Tier 3)", "better": 0, "matchers": [{"string": "Hall of Legends (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_legion_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Locks (Tier 2)", "better": 0, "matchers": [{"string": "Hall of Locks (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_strongbox_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Lords (Tier 2)", "better": 0, "matchers": [{"string": "Hall of Lords (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_queens_chambers_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Mettle (Tier 1)", "better": 0, "matchers": [{"string": "Hall of Mettle (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_legion_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Offerings (Tier 2)", "better": 0, "matchers": [{"string": "Hall of Offerings (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_sacrifice_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of War (Tier 3)", "better": 0, "matchers": [{"string": "Hall of War (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breeding_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Halls", "better": 0, "matchers": [{"string": "Halls"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_halls"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hatchery (Tier 1)", "better": 0, "matchers": [{"string": "Hatchery (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_minions_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: House of the Others (Tier 3)", "better": 0, "matchers": [{"string": "House of the Others (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breach_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hurricane Engine (Tier 2)", "better": 0, "matchers": [{"string": "Hurricane Engine (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_storm_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hybridisation Chamber (Tier 3)", "better": 0, "matchers": [{"string": "Hybridisation Chamber (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_minions_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Jeweller's Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Jeweller's Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trinket_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Jewellery Forge (Tier 2)", "better": 0, "matchers": [{"string": "Jewellery Forge (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trinket_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Lightning Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Lightning Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_lightning_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Locus of Corruption (Tier 3)", "better": 0, "matchers": [{"string": "Locus of Corruption (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_corruption_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Museum of Artefacts (Tier 3)", "better": 0, "matchers": [{"string": "Museum of Artefacts (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chests_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Office of Cartography (Tier 2)", "better": 0, "matchers": [{"string": "Office of Cartography (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cartography_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Omnitect Forge (Tier 2)", "better": 0, "matchers": [{"string": "Omnitect Forge (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_fire_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Omnitect Reactor Plant (Tier 2)", "better": 0, "matchers": [{"string": "Omnitect Reactor Plant (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_lightning_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Passageways", "better": 0, "matchers": [{"string": "Passageways"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_passageways"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Pits", "better": 0, "matchers": [{"string": "Pits"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_the_pits"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Poison Garden (Tier 1)", "better": 0, "matchers": [{"string": "Poison Garden (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_poison_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Pools of Restoration (Tier 1)", "better": 0, "matchers": [{"string": "Pools of Restoration (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_healing_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Royal Meeting Room (Tier 1)", "better": 0, "matchers": [{"string": "Royal Meeting Room (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_queens_chambers_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sacrificial Chamber (Tier 1)", "better": 0, "matchers": [{"string": "Sacrificial Chamber (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_sacrifice_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sadist's Den (Tier 3)", "better": 0, "matchers": [{"string": "Sadist's Den (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_torment_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sanctum of Immortality (Tier 3)", "better": 0, "matchers": [{"string": "Sanctum of Immortality (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_healing_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sanctum of Unity (Tier 2)", "better": 0, "matchers": [{"string": "Sanctum of Unity (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_empowering_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sanctum of Vitality (Tier 2)", "better": 0, "matchers": [{"string": "Sanctum of Vitality (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_healing_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Shrine of Empowerment (Tier 1)", "better": 0, "matchers": [{"string": "Shrine of Empowerment (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_empowering_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Shrine of Unmaking (Tier 3)", "better": 0, "matchers": [{"string": "Shrine of Unmaking (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_explosives_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sparring Room (Tier 1)", "better": 0, "matchers": [{"string": "Sparring Room (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_weapon_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Splinter Research Lab (Tier 1)", "better": 0, "matchers": [{"string": "Splinter Research Lab (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breach_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Storage Room (Tier 1)", "better": 0, "matchers": [{"string": "Storage Room (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chests_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Storm of Corruption (Tier 3)", "better": 0, "matchers": [{"string": "Storm of Corruption (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_storm_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Strongbox Chamber (Tier 1)", "better": 0, "matchers": [{"string": "Strongbox Chamber (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_strongbox_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Surveyor's Study (Tier 1)", "better": 0, "matchers": [{"string": "Surveyor's Study (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cartography_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Tempest Generator (Tier 1)", "better": 0, "matchers": [{"string": "Tempest Generator (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_storm_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Temple Defense Workshop (Tier 2)", "better": 0, "matchers": [{"string": "Temple Defense Workshop (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trap_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Temple Nexus (Tier 3)", "better": 0, "matchers": [{"string": "Temple Nexus (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_empowering_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Throne of Atziri (Tier 3)", "better": 0, "matchers": [{"string": "Throne of Atziri (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_queens_chambers_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Tombs", "better": 0, "matchers": [{"string": "Tombs"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_tombs"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Torment Cells (Tier 1)", "better": 0, "matchers": [{"string": "Torment Cells (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_torment_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Torture Cages (Tier 2)", "better": 0, "matchers": [{"string": "Torture Cages (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_torment_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Toxic Grove (Tier 3)", "better": 0, "matchers": [{"string": "Toxic Grove (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_poison_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Trap Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Trap Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trap_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Treasury (Tier 2)", "better": 0, "matchers": [{"string": "Treasury (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_currency_vault_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Tunnels", "better": 0, "matchers": [{"string": "Tunnels"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_tunnels"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Vault (Tier 1)", "better": 0, "matchers": [{"string": "Vault (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_currency_vault_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Warehouses (Tier 2)", "better": 0, "matchers": [{"string": "Warehouses (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chests_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Wealth of the Vaal (Tier 3)", "better": 0, "matchers": [{"string": "Wealth of the Vaal (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_currency_vault_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_workshop_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Shaper Influence", "better": 1, "matchers": [{"string": "Has Shaper Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_shaper_influence"]}}}
|
||||||
|
{"ref": "Has Warlord Influence", "better": 1, "matchers": [{"string": "Has Warlord Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_warlord_influence"]}}}
|
||||||
|
{"ref": "Mirrored Tablet has # Islands", "better": 1, "matchers": [{"string": "Mirrored Tablet has # Islands "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_lake_number_of_islands"]}}}
|
||||||
|
{"ref": "More Currency: #%", "better": 1, "matchers": [{"string": "More Currency: #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_currency_drops"]}}}
|
||||||
|
{"ref": "More Divination Cards: #%", "better": 1, "matchers": [{"string": "More Divination Cards: #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_card_drops"]}}}
|
||||||
|
{"ref": "More Maps: #%", "better": 1, "matchers": [{"string": "More Maps: #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_map_drops"]}}}
|
||||||
|
{"ref": "More Scarabs: #%", "better": 1, "matchers": [{"string": "More Scarabs: #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_scarab_drops"]}}}
|
||||||
|
{"ref": "Quality (Attack Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Attack Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_attack_quality"]}}}
|
||||||
|
{"ref": "Quality (Attribute Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Attribute Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_attribute_quality"]}}}
|
||||||
|
{"ref": "Quality (Caster Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Caster Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_caster_quality"]}}}
|
||||||
|
{"ref": "Quality (Critical Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Critical Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_critical_quality"]}}}
|
||||||
|
{"ref": "Quality (Currency): #%", "better": 1, "matchers": [{"string": "Quality (Currency): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_currency"]}}}
|
||||||
|
{"ref": "Quality (Defence Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Defence Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_defense_quality"]}}}
|
||||||
|
{"ref": "Quality (Divination Cards): #%", "better": 1, "matchers": [{"string": "Quality (Divination Cards): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_cards"]}}}
|
||||||
|
{"ref": "Quality (Elemental Damage Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Elemental Damage Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_elemental_quality"]}}}
|
||||||
|
{"ref": "Quality (Life and Mana Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Life and Mana Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_resource_quality"]}}}
|
||||||
|
{"ref": "Quality (Pack Size): #%", "better": 1, "matchers": [{"string": "Quality (Pack Size): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_pack_size"]}}}
|
||||||
|
{"ref": "Quality (Physical and Chaos Damage Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Physical and Chaos Damage Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_physical_chaos_quality"]}}}
|
||||||
|
{"ref": "Quality (Rarity): #%", "better": 1, "matchers": [{"string": "Quality (Rarity): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_rarity"]}}}
|
||||||
|
{"ref": "Quality (Resistance Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Resistance Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_resistance_quality"]}}}
|
||||||
|
{"ref": "Quality (Scarabs): #%", "better": 1, "matchers": [{"string": "Quality (Scarabs): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_scarabs"]}}}
|
||||||
|
{"ref": "Quality (Speed Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Speed Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_speed_quality"]}}}
|
||||||
|
{"ref": "Reflection of Abyss (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Abyss (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_38892"]}}}
|
||||||
|
{"ref": "Reflection of Ambush (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Ambush (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_48307"]}}}
|
||||||
|
{"ref": "Reflection of Angling (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Angling (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_40794"]}}}
|
||||||
|
{"ref": "Reflection of Azurite (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Azurite (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_40031"]}}}
|
||||||
|
{"ref": "Reflection of Bestiary (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Bestiary (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_55569"]}}}
|
||||||
|
{"ref": "Reflection of Breach (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Breach (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_62572"]}}}
|
||||||
|
{"ref": "Reflection of Brutality (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Brutality (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_29096"]}}}
|
||||||
|
{"ref": "Reflection of Camaraderie (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Camaraderie (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_35395"]}}}
|
||||||
|
{"ref": "Reflection of Catalysis (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Catalysis (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_57850"]}}}
|
||||||
|
{"ref": "Reflection of Chaos (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Chaos (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_50834"]}}}
|
||||||
|
{"ref": "Reflection of Conflict (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Conflict (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_1931"]}}}
|
||||||
|
{"ref": "Reflection of Darkness (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Darkness (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_34457"]}}}
|
||||||
|
{"ref": "Reflection of Delirium (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Delirium (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_22138"]}}}
|
||||||
|
{"ref": "Reflection of Delve (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Delve (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_18737"]}}}
|
||||||
|
{"ref": "Reflection of Demonfire (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Demonfire (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_28500"]}}}
|
||||||
|
{"ref": "Reflection of Domination (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Domination (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_63412"]}}}
|
||||||
|
{"ref": "Reflection of Entrapment (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Entrapment (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_44399"]}}}
|
||||||
|
{"ref": "Reflection of Essence (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Essence (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_49862"]}}}
|
||||||
|
{"ref": "Reflection of Experimentation (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Experimentation (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_55676"]}}}
|
||||||
|
{"ref": "Reflection of Flame (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Flame (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_42468"]}}}
|
||||||
|
{"ref": "Reflection of Fractured Dimensions (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Fractured Dimensions (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_49488"]}}}
|
||||||
|
{"ref": "Reflection of Frost (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Frost (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_38110"]}}}
|
||||||
|
{"ref": "Reflection of Guilt (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Guilt (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_25480"]}}}
|
||||||
|
{"ref": "Reflection of Imprisonment (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Imprisonment (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_10363"]}}}
|
||||||
|
{"ref": "Reflection of Kalandra (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Kalandra (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_36591"]}}}
|
||||||
|
{"ref": "Reflection of Legion (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Legion (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_403"]}}}
|
||||||
|
{"ref": "Reflection of Metamorph (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Metamorph (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_3699"]}}}
|
||||||
|
{"ref": "Reflection of Occultism (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Occultism (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_24451"]}}}
|
||||||
|
{"ref": "Reflection of Paradise (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Paradise (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_50846"]}}}
|
||||||
|
{"ref": "Reflection of Perverted Faith (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Perverted Faith (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_27678"]}}}
|
||||||
|
{"ref": "Reflection of Phaaryl (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Phaaryl (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_7674"]}}}
|
||||||
|
{"ref": "Reflection of Possession (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Possession (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_25049"]}}}
|
||||||
|
{"ref": "Reflection of Power (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Power (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_35950"]}}}
|
||||||
|
{"ref": "Reflection of Scourge (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Scourge (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_62360"]}}}
|
||||||
|
{"ref": "Reflection of Stasis (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Stasis (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_32968"]}}}
|
||||||
|
{"ref": "Reflection of Sulphite (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Sulphite (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_45086"]}}}
|
||||||
|
{"ref": "Reflection of the Black Scythe (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Black Scythe (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_9662"]}}}
|
||||||
|
{"ref": "Reflection of the Breachlord (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Breachlord (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_62935"]}}}
|
||||||
|
{"ref": "Reflection of the Broken Circle (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Broken Circle (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_43128"]}}}
|
||||||
|
{"ref": "Reflection of the Chalice (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Chalice (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_64561"]}}}
|
||||||
|
{"ref": "Reflection of the Chasm (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Chasm (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_57101"]}}}
|
||||||
|
{"ref": "Reflection of the Dream (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Dream (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_27117"]}}}
|
||||||
|
{"ref": "Reflection of the Harbingers (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Harbingers (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_37203"]}}}
|
||||||
|
{"ref": "Reflection of the Hunter (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Hunter (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_18816"]}}}
|
||||||
|
{"ref": "Reflection of the Monolith (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Monolith (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_34796"]}}}
|
||||||
|
{"ref": "Reflection of the Nightmare (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Nightmare (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_24232"]}}}
|
||||||
|
{"ref": "Reflection of the Storm (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Storm (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_2745"]}}}
|
||||||
|
{"ref": "Reflection of the Sun (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Sun (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_60034"]}}}
|
||||||
|
{"ref": "Reflection of the Trove (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Trove (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_46772"]}}}
|
||||||
|
{"ref": "Reflection of the Wilderness (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Wilderness (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_29224"]}}}
|
||||||
|
{"ref": "Reflection of Thralldom (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Thralldom (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_26813"]}}}
|
||||||
|
{"ref": "Reflection of Torment (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Torment (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_53950"]}}}
|
||||||
|
{"ref": "Reflection of Tyranny (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Tyranny (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_60981"]}}}
|
||||||
81
renderer/public/.DS_Store/vendor/pseudo-stats/cherry-pick-pseudo.py
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def get_script_dir():
|
||||||
|
"""Returns the directory where the script is located."""
|
||||||
|
return os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
# List of localization codes
|
||||||
|
localizations = ["en", "ru", "ko", "cmn-Hant"]
|
||||||
|
|
||||||
|
# File containing the pseudo keys to filter on
|
||||||
|
keys_file_path = (
|
||||||
|
f"{get_script_dir()}/pseudo_keys.ndjson" # Path to your ndjson pseudo keys file
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def load_pseudo_keys():
|
||||||
|
pseudo_keys = set()
|
||||||
|
with open(keys_file_path, "r", encoding="utf-8") as keys_file:
|
||||||
|
for line in keys_file:
|
||||||
|
try:
|
||||||
|
json_object = json.loads(line)
|
||||||
|
# Assume the pseudo keys are stored under the 'trade.ids.pseudo' path
|
||||||
|
if (
|
||||||
|
"trade" in json_object
|
||||||
|
and "ids" in json_object["trade"]
|
||||||
|
and "pseudo" in json_object["trade"]["ids"]
|
||||||
|
):
|
||||||
|
for key in json_object["trade"]["ids"]["pseudo"]:
|
||||||
|
pseudo_keys.add(key)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"Error parsing JSON in keys file: {e}")
|
||||||
|
return pseudo_keys
|
||||||
|
|
||||||
|
|
||||||
|
def process_localization_file(input_file_path, output_file_path, pseudo_keys):
|
||||||
|
result_list = []
|
||||||
|
|
||||||
|
with open(input_file_path, "r", encoding="utf-8") as input_file:
|
||||||
|
for line in input_file:
|
||||||
|
try:
|
||||||
|
json_object = json.loads(line)
|
||||||
|
# Check if 'trade.ids.pseudo' exists
|
||||||
|
if has_nested_key(json_object, "trade.ids.pseudo") and any(
|
||||||
|
value in pseudo_keys
|
||||||
|
for value in json_object["trade"]["ids"]["pseudo"]
|
||||||
|
):
|
||||||
|
result_list.append(json_object)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"Error parsing JSON: {e}")
|
||||||
|
|
||||||
|
with open(output_file_path, "w", encoding="utf-8") as output_file:
|
||||||
|
for item in result_list:
|
||||||
|
output_file.write(json.dumps(item, ensure_ascii=False) + "\n")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"Processing complete for {input_file_path}. Check {output_file_path} for results."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def has_nested_key(obj, key_path):
|
||||||
|
keys = key_path.split(".")
|
||||||
|
for key in keys:
|
||||||
|
if isinstance(obj, dict) and key in obj:
|
||||||
|
obj = obj[key]
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
pseudo_keys = load_pseudo_keys()
|
||||||
|
|
||||||
|
for loc in localizations:
|
||||||
|
input_file_path = f"{get_script_dir()}/../../data/{loc}/stats.ndjson.old" # Path to the input file
|
||||||
|
output_file_path = (
|
||||||
|
f"{get_script_dir()}/{loc}/pseudo_stats.ndjson" # Path to the output file
|
||||||
|
)
|
||||||
|
process_localization_file(input_file_path, output_file_path, pseudo_keys)
|
||||||
292
renderer/public/.DS_Store/vendor/pseudo-stats/cmn-Hant/all-pseudo.ndjson
vendored
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
{"ref": "# Crafted Modifiers", "better": 1, "matchers": [{"string": "# 工藝詞綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_crafted_mods"]}}}
|
||||||
|
{"ref": "# Crafted Prefix Modifiers", "better": 1, "matchers": [{"string": "# 工藝前綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_crafted_prefix_mods"]}}}
|
||||||
|
{"ref": "# Crafted Suffix Modifiers", "better": 1, "matchers": [{"string": "# 工藝後綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_crafted_suffix_mods"]}}}
|
||||||
|
{"ref": "# Empty Modifiers", "better": 1, "matchers": [{"string": "# 空詞綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_empty_affix_mods"]}}}
|
||||||
|
{"ref": "# Empty Prefix Modifiers", "better": 1, "matchers": [{"string": "# 空前綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_empty_prefix_mods"]}}}
|
||||||
|
{"ref": "# Empty Suffix Modifiers", "better": 1, "matchers": [{"string": "# 空後綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_empty_suffix_mods"]}}}
|
||||||
|
{"ref": "# Enchant Modifiers", "better": 1, "matchers": [{"string": "# 附魔詞綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_enchant_mods"]}}}
|
||||||
|
{"ref": "# Fractured Modifiers", "better": 1, "matchers": [{"string": "# 破裂詞綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_fractured_mods"]}}}
|
||||||
|
{"ref": "# Implicit Modifiers", "better": 1, "matchers": [{"string": "# 固定詞綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_implicit_mods"]}}}
|
||||||
|
{"ref": "# Life Regenerated per Second", "better": 1, "matchers": [{"string": "# 每秒生命回復 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_life_regen"]}}}
|
||||||
|
{"ref": "# Modifiers", "better": 1, "matchers": [{"string": "# 詞綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_affix_mods"]}}}
|
||||||
|
{"ref": "# Notable Passive Skills", "better": 1, "matchers": [{"string": "# 強力天賦 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_notable_passive_skills"]}}}
|
||||||
|
{"ref": "# Prefix Modifiers", "better": 1, "matchers": [{"string": "# 前綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_prefix_mods"]}}}
|
||||||
|
{"ref": "# Suffix Modifiers", "better": 1, "matchers": [{"string": "# 後綴 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_suffix_mods"]}}}
|
||||||
|
{"ref": "# total Elemental Resistances", "better": 1, "matchers": [{"string": "# 元素抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_count_elemental_resistances"]}}}
|
||||||
|
{"ref": "# total Resistances", "better": 1, "matchers": [{"string": "# 總抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_count_resistances"]}}}
|
||||||
|
{"ref": "#% Base Defence Percentile", "better": 1, "matchers": [{"string": "#% 基礎防禦百分比 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_base_defence_percentile"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Atlas Memories", "better": 1, "matchers": [{"string": "掉落的地圖有 #% 機率轉化至輿圖記憶 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_memory_line"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Conqueror Maps", "better": 1, "matchers": [{"string": "掉落的地圖有 #% 機率轉化至征服者地圖 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_conqueror_map"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Elder Maps", "better": 1, "matchers": [{"string": "掉落的地圖有 #% 機率轉化至尊師地圖 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_elder_map"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Maven Invitations", "better": 1, "matchers": [{"string": "掉落的地圖有 #% 機率轉化至釋界之邀 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_maven_invitation"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Scarabs", "better": 1, "matchers": [{"string": "掉落的地圖有 #% 機率轉化至聖甲蟲 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_scarab"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Shaper Maps", "better": 1, "matchers": [{"string": "掉落的地圖有 #% 機率轉化至塑界者地圖 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_shaper_map"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Unique Maps", "better": 1, "matchers": [{"string": "掉落的地圖有 #% 機率轉化至傳奇地圖 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_unique_map"]}}}
|
||||||
|
{"ref": "#% increased Burning Damage", "better": 1, "matchers": [{"string": "增加 #% 燃燒傷害"}, {"string": "減少 #% 燃燒傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_burning_damage"], "explicit": ["explicit.stat_1175385867"], "implicit": ["implicit.stat_1175385867"], "fractured": ["fractured.stat_1175385867"]}}}
|
||||||
|
{"ref": "#% increased Cold Damage", "better": 1, "matchers": [{"string": "增加 #% 冰冷傷害"}, {"string": "減少 #% 冰冷傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_damage"], "explicit": ["explicit.stat_3291658075"], "implicit": ["implicit.stat_3291658075"], "fractured": ["fractured.stat_3291658075"], "scourge": ["scourge.stat_3291658075"], "crafted": ["crafted.stat_3291658075"]}}}
|
||||||
|
{"ref": "#% increased Cold Damage with Attack Skills", "better": 1, "matchers": [{"string": "攻擊技能增加 #% 冰冷傷害"}, {"string": "攻擊技能減少 #% 冰冷傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_damage_with_attack_skills"], "explicit": ["explicit.stat_860668586"], "implicit": ["implicit.stat_860668586"]}}}
|
||||||
|
{"ref": "#% increased Cold Spell Damage", "better": 1, "matchers": [{"string": "增加 #% 冰冷法術傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Elemental Damage", "better": 1, "matchers": [{"string": "增加 #% 元素傷害"}, {"string": "有增加 #% 的元素傷害"}, {"string": "有減少 #% 的元素傷害", "negate": true}, {"string": "減少 #% 元素傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_elemental_damage"], "explicit": ["explicit.stat_3141070085"], "implicit": ["implicit.stat_3141070085"], "fractured": ["fractured.stat_3141070085"], "scourge": ["scourge.stat_3141070085"]}}}
|
||||||
|
{"ref": "#% increased Elemental Damage with Attack Skills", "better": 1, "matchers": [{"string": "攻擊技能增加 #% 元素傷害"}, {"string": "攻擊技能減少 #% 元素傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_elemental_damage_with_attack_skills"], "explicit": ["explicit.stat_387439868"], "implicit": ["implicit.stat_387439868"], "fractured": ["fractured.stat_387439868"], "scourge": ["scourge.stat_387439868"], "crafted": ["crafted.stat_387439868"]}}}
|
||||||
|
{"ref": "#% increased Fire Damage", "better": 1, "matchers": [{"string": "增加 #% 火焰傷害"}, {"string": "減少 #% 火焰傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_damage"], "explicit": ["explicit.stat_3962278098"], "implicit": ["implicit.stat_3962278098"], "fractured": ["fractured.stat_3962278098"], "scourge": ["scourge.stat_3962278098"], "crafted": ["crafted.stat_3962278098"]}}}
|
||||||
|
{"ref": "#% increased Fire Damage with Attack Skills", "better": 1, "matchers": [{"string": "攻擊技能增加 #% 火焰傷害"}, {"string": "攻擊技能減少 #% 火焰傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_damage_with_attack_skills"], "implicit": ["implicit.stat_2468413380"]}}}
|
||||||
|
{"ref": "#% increased Fire Spell Damage", "better": 1, "matchers": [{"string": "增加 #% 火焰法術傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Lightning Damage", "better": 1, "matchers": [{"string": "增加 #% 閃電傷害"}, {"string": "減少 #% 閃電傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_damage"], "explicit": ["explicit.stat_2231156303"], "implicit": ["implicit.stat_2231156303"], "fractured": ["fractured.stat_2231156303"], "scourge": ["scourge.stat_2231156303"], "crafted": ["crafted.stat_2231156303"]}}}
|
||||||
|
{"ref": "#% increased Lightning Damage with Attack Skills", "better": 1, "matchers": [{"string": "攻擊技能增加 #% 閃電傷害"}, {"string": "攻擊技能減少 #% 閃電傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_damage_with_attack_skills"], "explicit": ["explicit.stat_4208907162"], "implicit": ["implicit.stat_4208907162"]}}}
|
||||||
|
{"ref": "#% increased Lightning Spell Damage", "better": 1, "matchers": [{"string": "增加 #% 閃電法術傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Mana Regeneration Rate", "better": 1, "matchers": [{"string": "增加 #% 魔力回復率"}, {"string": "減少 #% 魔力回復率", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_mana_regen"], "explicit": ["explicit.stat_789117908"], "implicit": ["implicit.stat_789117908"], "fractured": ["fractured.stat_789117908"], "scourge": ["scourge.stat_789117908"], "crafted": ["crafted.stat_789117908"]}}}
|
||||||
|
{"ref": "#% increased Movement Speed", "better": 1, "matchers": [{"string": "增加 #% 移動速度"}, {"string": "減少 #% 移動速度", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_movement_speed"], "explicit": ["explicit.stat_2250533757"], "implicit": ["implicit.stat_2250533757"], "fractured": ["fractured.stat_2250533757"], "enchant": ["enchant.stat_2250533757"], "scourge": ["scourge.stat_2250533757"], "crafted": ["crafted.stat_2250533757"]}}}
|
||||||
|
{"ref": "#% increased Rarity of Items found", "better": 1, "matchers": [{"string": "增加 #% 物品稀有度"}, {"string": "減少 #% 物品稀有度", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_rarity"], "explicit": ["explicit.stat_3917489142"], "implicit": ["implicit.stat_3917489142"], "fractured": ["fractured.stat_3917489142"], "scourge": ["scourge.stat_3917489142"], "crafted": ["crafted.stat_3917489142"]}}}
|
||||||
|
{"ref": "#% increased Spell Damage", "better": 1, "matchers": [{"string": "增加 #% 法術傷害"}, {"string": "減少 #% 法術傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_spell_damage"], "explicit": ["explicit.stat_2974417149"], "implicit": ["implicit.stat_2974417149"], "fractured": ["fractured.stat_2974417149"], "enchant": ["enchant.stat_2974417149"], "scourge": ["scourge.stat_2974417149"], "crafted": ["crafted.stat_2974417149"]}}}
|
||||||
|
{"ref": "#% of Life Regenerated per Second", "better": 1, "matchers": [{"string": "每秒回復 #% 生命 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_percent_life_regen"]}}}
|
||||||
|
{"ref": "#% of Physical Attack Damage Leeched as Life", "dp": true, "better": 1, "matchers": [{"string": "#% 的物理攻擊傷害偷取生命"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_physical_attack_damage_leeched_as_life"], "explicit": ["explicit.stat_3593843976", "explicit.stat_55876295"], "implicit": ["implicit.stat_3593843976", "implicit.stat_55876295"], "fractured": ["fractured.stat_3593843976", "fractured.stat_55876295"], "scourge": ["scourge.stat_3593843976"], "crafted": ["crafted.stat_3593843976", "crafted.stat_55876295"]}}}
|
||||||
|
{"ref": "#% of Physical Attack Damage Leeched as Mana", "dp": true, "better": 1, "matchers": [{"string": "#% 物理攻擊傷害偷取魔力"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_physical_attack_damage_leeched_as_mana"], "explicit": ["explicit.stat_3237948413", "explicit.stat_669069897"], "implicit": ["implicit.stat_3237948413", "implicit.stat_669069897"], "fractured": ["fractured.stat_3237948413", "fractured.stat_669069897"], "scourge": ["scourge.stat_3237948413"], "crafted": ["crafted.stat_3237948413", "crafted.stat_669069897"]}}}
|
||||||
|
{"ref": "#% total increased maximum Energy Shield", "better": 1, "matchers": [{"string": "增加 #% 最大能量護盾 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_energy_shield"]}}}
|
||||||
|
{"ref": "#% total increased Physical Damage", "better": 1, "matchers": [{"string": "增加 #% 物裡傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_physical_damage"]}}}
|
||||||
|
{"ref": "+# total maximum Energy Shield", "better": 1, "matchers": [{"string": "+# 最大能量護盾 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_energy_shield"]}}}
|
||||||
|
{"ref": "+# total maximum Life", "better": 1, "matchers": [{"string": "+# 最大生命 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_life"]}}}
|
||||||
|
{"ref": "+# total maximum Mana", "better": 1, "matchers": [{"string": "+# 最大魔力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_mana"]}}}
|
||||||
|
{"ref": "+# total to all Attributes", "better": 1, "matchers": [{"string": "+# 全能力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_all_attributes"]}}}
|
||||||
|
{"ref": "+# total to Dexterity", "better": 1, "matchers": [{"string": "+# 敏捷 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_dexterity"]}}}
|
||||||
|
{"ref": "+# total to Intelligence", "better": 1, "matchers": [{"string": "+# 智慧 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_intelligence"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Aura Gems", "better": 1, "matchers": [{"string": "+# 插槽中光環寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_aura_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Bow Gems", "better": 1, "matchers": [{"string": "+# 插槽中弓寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_bow_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Chaos Gems", "better": 1, "matchers": [{"string": "+# 插槽中混沌寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_chaos_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Cold Gems", "better": 1, "matchers": [{"string": "+# 插槽中冰冷寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_cold_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Curse Gems", "better": 1, "matchers": [{"string": "+# 插槽中詛咒寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_curse_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Dexterity Gems", "better": 1, "matchers": [{"string": "+# 插槽中敏捷寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_dexterity_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Elemental Gems", "better": 1, "matchers": [{"string": "+# 插槽中元素寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_elemental_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Fire Gems", "better": 1, "matchers": [{"string": "+# 插槽中火焰寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_fire_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Gems", "better": 1, "matchers": [{"string": "+# 插槽中寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Golem Gems", "better": 1, "matchers": [{"string": "+# 插槽中魔像寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_golem_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Intelligence Gems", "better": 1, "matchers": [{"string": "+# 插槽中智慧寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_intelligence_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Lightning Gems", "better": 1, "matchers": [{"string": "+# 插槽中閃電寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_lightning_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Melee Gems", "better": 1, "matchers": [{"string": "+# 插槽中近戰寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_melee_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Minion Gems", "better": 1, "matchers": [{"string": "+# 插槽中召喚物寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_minion_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Movement Gems", "better": 1, "matchers": [{"string": "+# 插槽中位移寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_movement_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Projectile Gems", "better": 1, "matchers": [{"string": "+# 插槽中投射物寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_projectile_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Skill Gems", "better": 1, "matchers": [{"string": "+# 插槽中技能寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_skill_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Spell Gems", "better": 1, "matchers": [{"string": "+# 插槽中法術寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_spell_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Strength Gems", "better": 1, "matchers": [{"string": "+# 插槽中力量寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_strength_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Support Gems", "better": 1, "matchers": [{"string": "+# 插槽中輔助寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_support_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Vaal Gems", "better": 1, "matchers": [{"string": "+# 插槽中瓦爾寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_vaal_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Warcry Gems", "better": 1, "matchers": [{"string": "+# 插槽中戰吼寶石等級 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_warcry_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Strength", "better": 1, "matchers": [{"string": "+# 力量 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_strength"]}}}
|
||||||
|
{"ref": "+#% Global Critical Strike Chance", "better": 1, "matchers": [{"string": "+#% 全域暴擊機率 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_global_critical_strike_chance"]}}}
|
||||||
|
{"ref": "+#% Global Critical Strike Multiplier", "better": 1, "matchers": [{"string": "+#% 全域暴擊加成 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_global_critical_strike_multiplier"]}}}
|
||||||
|
{"ref": "+#% total Attack Speed", "better": 1, "matchers": [{"string": "+#% 攻擊速度 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_attack_speed"]}}}
|
||||||
|
{"ref": "+#% total Cast Speed", "better": 1, "matchers": [{"string": "+#% 施放速度 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_cast_speed"]}}}
|
||||||
|
{"ref": "+#% total Critical Strike Chance for Spells", "better": 1, "matchers": [{"string": "+#% 法術暴擊機率 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_critical_strike_chance_for_spells"]}}}
|
||||||
|
{"ref": "+#% total Elemental Resistance", "better": 1, "matchers": [{"string": "+#% 元素抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_elemental_resistance"]}}}
|
||||||
|
{"ref": "+#% total Resistance", "better": 1, "matchers": [{"string": "+#% 總抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_resistance"]}}}
|
||||||
|
{"ref": "+#% total to all Elemental Resistances", "better": 1, "matchers": [{"string": "+#% 元素抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_all_elemental_resistances"]}}}
|
||||||
|
{"ref": "+#% total to Chaos Resistance", "better": 1, "matchers": [{"string": "+#% 總混沌抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_chaos_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Cold Resistance", "better": 1, "matchers": [{"string": "+#% 冰冷抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_cold_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Fire Resistance", "better": 1, "matchers": [{"string": "+#% 火焰抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_fire_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Lightning Resistance", "better": 1, "matchers": [{"string": "+#% 閃電抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_lightning_resistance"]}}}
|
||||||
|
{"ref": "Adds # to # Chaos Damage", "better": 1, "matchers": [{"string": "附加 # 至 # 混沌傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_chaos_damage"], "explicit": ["explicit.stat_2223678961", "explicit.stat_3531280422"], "implicit": ["implicit.stat_2223678961", "implicit.stat_3531280422"], "fractured": ["fractured.stat_2223678961"], "enchant": ["enchant.stat_2223678961"], "scourge": ["scourge.stat_2223678961"]}}}
|
||||||
|
{"ref": "Adds # to # Chaos Damage to Attacks", "better": 1, "matchers": [{"string": "攻擊附加 # 至 # 混沌傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_chaos_damage_to_attacks"], "explicit": ["explicit.stat_674553446"], "implicit": ["implicit.stat_674553446"], "fractured": ["fractured.stat_674553446"], "crafted": ["crafted.stat_674553446"]}}}
|
||||||
|
{"ref": "Adds # to # Chaos Damage to Spells", "better": 1, "matchers": [{"string": "法術附加 # 至 # 混沌傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_chaos_damage_to_spells"], "explicit": ["explicit.stat_2300399854"], "implicit": ["implicit.stat_2300399854"], "fractured": ["fractured.stat_2300399854"]}}}
|
||||||
|
{"ref": "Adds # to # Cold Damage", "better": 1, "matchers": [{"string": "附加 # 至 # 冰冷傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_cold_damage"], "explicit": ["explicit.stat_1037193709", "explicit.stat_2387423236"], "implicit": ["implicit.stat_1037193709", "implicit.stat_2387423236"], "fractured": ["fractured.stat_1037193709", "fractured.stat_2387423236"], "enchant": ["enchant.stat_1037193709"], "scourge": ["scourge.stat_1037193709"], "crafted": ["crafted.stat_1037193709", "crafted.stat_2387423236"]}}}
|
||||||
|
{"ref": "Adds # to # Cold Damage to Attacks", "better": 1, "matchers": [{"string": "攻擊附加 # 至 # 冰冷傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_cold_damage_to_attacks"], "explicit": ["explicit.stat_4067062424"], "implicit": ["implicit.stat_4067062424"], "fractured": ["fractured.stat_4067062424"], "crafted": ["crafted.stat_4067062424"]}}}
|
||||||
|
{"ref": "Adds # to # Cold Damage to Spells", "better": 1, "matchers": [{"string": "法術附加 # 至 # 冰冷傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_cold_damage_to_spells"], "explicit": ["explicit.stat_2469416729"], "implicit": ["implicit.stat_2469416729"], "fractured": ["fractured.stat_2469416729"], "scourge": ["scourge.stat_2469416729"], "crafted": ["crafted.stat_2469416729"]}}}
|
||||||
|
{"ref": "Adds # to # Damage", "better": 1, "matchers": [{"string": "附加 # 至 # 傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_damage"]}}}
|
||||||
|
{"ref": "Adds # to # Damage to Attacks", "better": 1, "matchers": [{"string": "攻擊附加 # 至 # 傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_damage_to_attacks"]}}}
|
||||||
|
{"ref": "Adds # to # Damage to Spells", "better": 1, "matchers": [{"string": "法術附加 # 至 # 傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_damage_to_spells"]}}}
|
||||||
|
{"ref": "Adds # to # Elemental Damage", "better": 1, "matchers": [{"string": "附加 # 至 # 元素傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_elemental_damage"]}}}
|
||||||
|
{"ref": "Adds # to # Elemental Damage to Attacks", "better": 1, "matchers": [{"string": "攻擊附加 # 至 # 元素傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_elemental_damage_to_attacks"]}}}
|
||||||
|
{"ref": "Adds # to # Elemental Damage to Spells", "better": 1, "matchers": [{"string": "法術附加 # 至 # 元素傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_elemental_damage_to_spells"]}}}
|
||||||
|
{"ref": "Adds # to # Fire Damage", "better": 1, "matchers": [{"string": "附加 # 至 # 火焰傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_fire_damage"], "explicit": ["explicit.stat_321077055", "explicit.stat_709508406"], "implicit": ["implicit.stat_321077055", "implicit.stat_709508406"], "fractured": ["fractured.stat_321077055", "fractured.stat_709508406"], "enchant": ["enchant.stat_709508406"], "scourge": ["scourge.stat_709508406"], "crafted": ["crafted.stat_321077055", "crafted.stat_709508406"]}}}
|
||||||
|
{"ref": "Adds # to # Fire Damage to Attacks", "better": 1, "matchers": [{"string": "攻擊附加 # 至 # 火焰傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_fire_damage_to_attacks"], "explicit": ["explicit.stat_1573130764"], "implicit": ["implicit.stat_1573130764"], "fractured": ["fractured.stat_1573130764"], "crafted": ["crafted.stat_1573130764"]}}}
|
||||||
|
{"ref": "Adds # to # Fire Damage to Spells", "better": 1, "matchers": [{"string": "法術附加 # 至 # 火焰傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_fire_damage_to_spells"], "explicit": ["explicit.stat_1133016593"], "implicit": ["implicit.stat_1133016593"], "fractured": ["fractured.stat_1133016593"], "scourge": ["scourge.stat_1133016593"], "crafted": ["crafted.stat_1133016593"]}}}
|
||||||
|
{"ref": "Adds # to # Lightning Damage", "better": 1, "matchers": [{"string": "附加 # 至 # 閃電傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_lightning_damage"], "explicit": ["explicit.stat_1334060246", "explicit.stat_3336890334"], "implicit": ["implicit.stat_1334060246", "implicit.stat_3336890334"], "fractured": ["fractured.stat_1334060246", "fractured.stat_3336890334"], "enchant": ["enchant.stat_3336890334"], "scourge": ["scourge.stat_3336890334"], "crafted": ["crafted.stat_1334060246", "crafted.stat_3336890334"]}}}
|
||||||
|
{"ref": "Adds # to # Lightning Damage to Attacks", "better": 1, "matchers": [{"string": "攻擊附加 # 至 # 閃電傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_lightning_damage_to_attacks"], "explicit": ["explicit.stat_1754445556"], "implicit": ["implicit.stat_1754445556"], "fractured": ["fractured.stat_1754445556"], "crafted": ["crafted.stat_1754445556"]}}}
|
||||||
|
{"ref": "Adds # to # Lightning Damage to Spells", "better": 1, "matchers": [{"string": "法術附加 # 至 # 閃電傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_lightning_damage_to_spells"], "explicit": ["explicit.stat_2831165374"], "implicit": ["implicit.stat_2831165374"], "fractured": ["fractured.stat_2831165374"], "scourge": ["scourge.stat_2831165374"], "crafted": ["crafted.stat_2831165374"]}}}
|
||||||
|
{"ref": "Adds # to # Physical Damage", "better": 1, "matchers": [{"string": "附加 # 至 # 物理傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_physical_damage"], "explicit": ["explicit.stat_1940865751", "explicit.stat_960081730"], "implicit": ["implicit.stat_1940865751"], "fractured": ["fractured.stat_1940865751"], "scourge": ["scourge.stat_1940865751"], "crafted": ["crafted.stat_1940865751"]}}}
|
||||||
|
{"ref": "Adds # to # Physical Damage to Attacks", "better": 1, "matchers": [{"string": "攻擊附加 # 至 # 物理傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_physical_damage_to_attacks"], "explicit": ["explicit.stat_3032590688"], "implicit": ["implicit.stat_3032590688"], "fractured": ["fractured.stat_3032590688"], "crafted": ["crafted.stat_3032590688"]}}}
|
||||||
|
{"ref": "Adds # to # Physical Damage to Spells", "better": 1, "matchers": [{"string": "法術附加 # 至 # 物理傷害"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_physical_damage_to_spells"], "explicit": ["explicit.stat_2435536961"], "implicit": ["implicit.stat_2435536961"], "fractured": ["fractured.stat_2435536961"], "scourge": ["scourge.stat_2435536961"]}}}
|
||||||
|
{"ref": "Has # Influences", "better": 1, "matchers": [{"string": "有 # 勢力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_influence_count"]}}}
|
||||||
|
{"ref": "Has Crusader Influence", "better": 1, "matchers": [{"string": "有聖戰軍王勢力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_crusader_influence"]}}}
|
||||||
|
{"ref": "Has Elder Influence", "better": 1, "matchers": [{"string": "有尊師勢力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_elder_influence"]}}}
|
||||||
|
{"ref": "Has Hunter Influence", "better": 1, "matchers": [{"string": "有狩獵者勢力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_hunter_influence"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Battleground Graves", "better": 1, "matchers": [{"string": "有日誌區域:烽火墳墓 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_battleground_graves"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Bluffs", "better": 1, "matchers": [{"string": "有日誌區域:陡岸峭壁 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_bluffs"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Cemetery", "better": 1, "matchers": [{"string": "有日誌區域:公墓 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_cemetery"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Desert Ruins", "better": 1, "matchers": [{"string": "有日誌區域:沙漠廢墟 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_desert_ruins"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Dried Riverbed", "better": 1, "matchers": [{"string": "有日誌區域:乾枯河床 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_dried_riverbed"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Forest Ruins", "better": 1, "matchers": [{"string": "有日誌區域:森林遺跡 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_forest_ruins"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Karui Wargraves", "better": 1, "matchers": [{"string": "有日誌區域:卡魯戰爭墓地 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_karui_wargraves"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Mountainside", "better": 1, "matchers": [{"string": "有日誌區域:迷黯山腰 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_mountainside"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Rotting Temple", "better": 1, "matchers": [{"string": "有日誌區域:腐朽神殿 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_rotting_temple"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Sarn Slums", "better": 1, "matchers": [{"string": "有日誌區域:薩恩貧民窟 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_sarn_slums"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Scrublands", "better": 1, "matchers": [{"string": "有日誌區域:灌木叢 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_scrublands"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Shipwreck Reef", "better": 1, "matchers": [{"string": "有日誌區域:沉船岩礁 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_shipwreck_reef"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Utzaal Outskirts", "better": 1, "matchers": [{"string": "有日誌區域:奧札爾郊野 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_utzaal_outskirts"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Vaal Temple", "better": 1, "matchers": [{"string": "有日誌區域:瓦爾神殿 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_vaal_temple"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Volcanic Island", "better": 1, "matchers": [{"string": "有日誌區域:火山島 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_volcano"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Black Scythe Mercenaries", "better": 0, "matchers": [{"string": "黑鐮傭兵"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_mercenaries"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Druids of the Broken Circle", "better": 0, "matchers": [{"string": "破碎環之德魯伊"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_druids"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Knights of the Sun", "better": 0, "matchers": [{"string": "豔陽騎士"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_knights"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Order of the Chalice", "better": 0, "matchers": [{"string": "聖杯之序"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_order"]}}}
|
||||||
|
{"ref": "Has Redeemer Influence", "better": 1, "matchers": [{"string": "有救贖者勢力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_redeemer_influence"]}}}
|
||||||
|
{"ref": "Has Room: Antechamber", "better": 0, "matchers": [{"string": "神殿前院"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_antechamber"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Apex of Ascension (Tier 3)", "better": 0, "matchers": [{"string": "祭祀之巔 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_sacrifice_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Apex of Atzoatl", "better": 0, "matchers": [{"string": "阿茲瓦特之巔"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_apex"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Arena of Valour (Tier 2)", "better": 0, "matchers": [{"string": "傳說對決 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_weapon_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Armourer's Workshop (Tier 1)", "better": 0, "matchers": [{"string": "裝甲磨坊 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_armour_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Armoury (Tier 2)", "better": 0, "matchers": [{"string": "軍械庫 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_armour_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Atlas of Worlds (Tier 3)", "better": 0, "matchers": [{"string": "異界輿圖 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cartography_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Automaton Lab (Tier 2)", "better": 0, "matchers": [{"string": "自運研究所 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_minions_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Banquet Hall", "better": 0, "matchers": [{"string": "神殿宴會場"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_banquet_hall"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Barracks (Tier 2)", "better": 0, "matchers": [{"string": "軍隊憩所 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breeding_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Breach Containment Chamber (Tier 2)", "better": 0, "matchers": [{"string": "裂痕異域室 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breach_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Catalyst of Corruption (Tier 2)", "better": 0, "matchers": [{"string": "腐敗孳生室 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_corruption_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Cellar", "better": 0, "matchers": [{"string": "神殿地窖"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cellar"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Chamber of Iron (Tier 3)", "better": 0, "matchers": [{"string": "鋼鍛之室 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_armour_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Chasm", "better": 0, "matchers": [{"string": "神殿裂口"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chasm_room"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Cloister", "better": 0, "matchers": [{"string": "神殿廟"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cloister"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Conduit of Lightning (Tier 3)", "better": 0, "matchers": [{"string": "雷霆導管 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_lightning_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Corruption Chamber (Tier 1)", "better": 0, "matchers": [{"string": "腐敗之室 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_corruption_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Court of Sealed Death (Tier 3)", "better": 0, "matchers": [{"string": "封亡院庭 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_strongbox_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Crucible of Flame (Tier 3)", "better": 0, "matchers": [{"string": "烈焰熔爐 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_fire_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Cultivar Chamber (Tier 2)", "better": 0, "matchers": [{"string": "培育秘室 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_poison_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Defense Research Lab (Tier 3)", "better": 0, "matchers": [{"string": "禦防研究所 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trap_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Demolition Lab (Tier 2)", "better": 0, "matchers": [{"string": "拆除庫 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_explosives_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Department of Thaumaturgy (Tier 2)", "better": 0, "matchers": [{"string": "魔法部 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_gem_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Doryani's Institute (Tier 3)", "better": 0, "matchers": [{"string": "多里亞尼之院 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_gem_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Engineering Department (Tier 2)", "better": 0, "matchers": [{"string": "工程部 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_workshop_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Explosives Room (Tier 1)", "better": 0, "matchers": [{"string": "彈藥庫 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_explosives_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Factory (Tier 3)", "better": 0, "matchers": [{"string": "瓦爾工廠 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_workshop_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Flame Workshop (Tier 1)", "better": 0, "matchers": [{"string": "獄炎磨坊 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_fire_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Gemcutter's Workshop (Tier 1)", "better": 0, "matchers": [{"string": "刻石磨坊 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_gem_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Glittering Halls (Tier 3)", "better": 0, "matchers": [{"string": "閃耀聖殿 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trinket_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Guardhouse (Tier 1)", "better": 0, "matchers": [{"string": "衛兵房 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breeding_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Champions (Tier 3)", "better": 0, "matchers": [{"string": "冠軍聖殿 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_weapon_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Heroes (Tier 2)", "better": 0, "matchers": [{"string": "英雄之殿 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_legion_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Legends (Tier 3)", "better": 0, "matchers": [{"string": "神話之殿 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_legion_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Locks (Tier 2)", "better": 0, "matchers": [{"string": "千鎖殿堂 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_strongbox_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Lords (Tier 2)", "better": 0, "matchers": [{"string": "權貴殿堂 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_queens_chambers_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Mettle (Tier 1)", "better": 0, "matchers": [{"string": "勇氣之殿 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_legion_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Offerings (Tier 2)", "better": 0, "matchers": [{"string": "獻祭殿堂 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_sacrifice_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of War (Tier 3)", "better": 0, "matchers": [{"string": "戰爭聖殿 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breeding_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Halls", "better": 0, "matchers": [{"string": "神殿殿堂"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_halls"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hatchery (Tier 1)", "better": 0, "matchers": [{"string": "孵化室 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_minions_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: House of the Others (Tier 3)", "better": 0, "matchers": [{"string": "異者居所 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breach_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hurricane Engine (Tier 2)", "better": 0, "matchers": [{"string": "颶風引擎室 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_storm_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hybridisation Chamber (Tier 3)", "better": 0, "matchers": [{"string": "異種之域 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_minions_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Jeweller's Workshop (Tier 1)", "better": 0, "matchers": [{"string": "寶匠磨坊 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trinket_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Jewellery Forge (Tier 2)", "better": 0, "matchers": [{"string": "珠寶冶煉室 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trinket_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Lightning Workshop (Tier 1)", "better": 0, "matchers": [{"string": "風雷磨坊 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_lightning_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Locus of Corruption (Tier 3)", "better": 0, "matchers": [{"string": "腐敗之地 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_corruption_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Museum of Artefacts (Tier 3)", "better": 0, "matchers": [{"string": "文物展館 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chests_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Office of Cartography (Tier 2)", "better": 0, "matchers": [{"string": "製圖研製室 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cartography_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Omnitect Forge (Tier 2)", "better": 0, "matchers": [{"string": "全能冶煉室 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_fire_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Omnitect Reactor Plant (Tier 2)", "better": 0, "matchers": [{"string": "全能反應廠 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_lightning_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Passageways", "better": 0, "matchers": [{"string": "神殿通道"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_passageways"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Pits", "better": 0, "matchers": [{"string": "神殿舊窖"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_the_pits"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Poison Garden (Tier 1)", "better": 0, "matchers": [{"string": "監獄花園 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_poison_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Pools of Restoration (Tier 1)", "better": 0, "matchers": [{"string": "治癒之泉 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_healing_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Royal Meeting Room (Tier 1)", "better": 0, "matchers": [{"string": "王室宴客室 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_queens_chambers_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sacrificial Chamber (Tier 1)", "better": 0, "matchers": [{"string": "獻祭之室 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_sacrifice_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sadist's Den (Tier 3)", "better": 0, "matchers": [{"string": "虐狂之巢 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_torment_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sanctum of Immortality (Tier 3)", "better": 0, "matchers": [{"string": "不朽聖殿 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_healing_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sanctum of Unity (Tier 2)", "better": 0, "matchers": [{"string": "統領聖殿 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_empowering_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sanctum of Vitality (Tier 2)", "better": 0, "matchers": [{"string": "活力聖殿 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_healing_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Shrine of Empowerment (Tier 1)", "better": 0, "matchers": [{"string": "恩賜神殿 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_empowering_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Shrine of Unmaking (Tier 3)", "better": 0, "matchers": [{"string": "毀滅神殿 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_explosives_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sparring Room (Tier 1)", "better": 0, "matchers": [{"string": "格鬥場 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_weapon_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Splinter Research Lab (Tier 1)", "better": 0, "matchers": [{"string": "裂界研究所 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breach_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Storage Room (Tier 1)", "better": 0, "matchers": [{"string": "儲物室 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chests_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Storm of Corruption (Tier 3)", "better": 0, "matchers": [{"string": "腐敗風暴 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_storm_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Strongbox Chamber (Tier 1)", "better": 0, "matchers": [{"string": "寶箱之殿 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_strongbox_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Surveyor's Study (Tier 1)", "better": 0, "matchers": [{"string": "研究書房 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cartography_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Tempest Generator (Tier 1)", "better": 0, "matchers": [{"string": "暴雷發電室 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_storm_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Temple Defense Workshop (Tier 2)", "better": 0, "matchers": [{"string": "神殿禦防室 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trap_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Temple Nexus (Tier 3)", "better": 0, "matchers": [{"string": "死神靈殿 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_empowering_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Throne of Atziri (Tier 3)", "better": 0, "matchers": [{"string": "阿茲里宴殿 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_queens_chambers_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Tombs", "better": 0, "matchers": [{"string": "神殿陵寢"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_tombs"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Torment Cells (Tier 1)", "better": 0, "matchers": [{"string": "磨難牢房 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_torment_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Torture Cages (Tier 2)", "better": 0, "matchers": [{"string": "拷刑大牢 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_torment_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Toxic Grove (Tier 3)", "better": 0, "matchers": [{"string": "劇毒果園 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_poison_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Trap Workshop (Tier 1)", "better": 0, "matchers": [{"string": "陷阱磨坊 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trap_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Treasury (Tier 2)", "better": 0, "matchers": [{"string": "祕寶庫 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_currency_vault_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Tunnels", "better": 0, "matchers": [{"string": "神殿地道"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_tunnels"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Vault (Tier 1)", "better": 0, "matchers": [{"string": "藏寶庫 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_currency_vault_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Warehouses (Tier 2)", "better": 0, "matchers": [{"string": "倉庫間 (階級 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chests_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Wealth of the Vaal (Tier 3)", "better": 0, "matchers": [{"string": "瓦爾聚寶庫 (階級 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_currency_vault_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Workshop (Tier 1)", "better": 0, "matchers": [{"string": "工作坊 (階級 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_workshop_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Shaper Influence", "better": 1, "matchers": [{"string": "有塑者勢力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_shaper_influence"]}}}
|
||||||
|
{"ref": "Has Warlord Influence", "better": 1, "matchers": [{"string": "有總督軍勢力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_warlord_influence"]}}}
|
||||||
|
{"ref": "Mirrored Tablet has # Islands", "better": 1, "matchers": [{"string": "鏡像碑牌有 # 島嶼 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_lake_number_of_islands"]}}}
|
||||||
|
{"ref": "More Currency: #%", "better": 1, "matchers": [{"string": "更多通貨:#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_currency_drops"]}}}
|
||||||
|
{"ref": "More Divination Cards: #%", "better": 1, "matchers": [{"string": "額外命運卡:#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_card_drops"]}}}
|
||||||
|
{"ref": "More Maps: #%", "better": 1, "matchers": [{"string": "更多地圖:#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_map_drops"]}}}
|
||||||
|
{"ref": "More Scarabs: #%", "better": 1, "matchers": [{"string": "更多聖甲蟲:#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_scarab_drops"]}}}
|
||||||
|
{"ref": "Quality (Attack Modifiers): #%", "better": 1, "matchers": [{"string": "品質(攻擊詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_attack_quality"]}}}
|
||||||
|
{"ref": "Quality (Attribute Modifiers): #%", "better": 1, "matchers": [{"string": "品質(能力值詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_attribute_quality"]}}}
|
||||||
|
{"ref": "Quality (Caster Modifiers): #%", "better": 1, "matchers": [{"string": "品質(法術詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_caster_quality"]}}}
|
||||||
|
{"ref": "Quality (Critical Modifiers): #%", "better": 1, "matchers": [{"string": "品質(暴擊詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_critical_quality"]}}}
|
||||||
|
{"ref": "Quality (Currency): #%", "better": 1, "matchers": [{"string": "品質(通貨):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_currency"]}}}
|
||||||
|
{"ref": "Quality (Defence Modifiers): #%", "better": 1, "matchers": [{"string": "品質(防禦詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_defense_quality"]}}}
|
||||||
|
{"ref": "Quality (Divination Cards): #%", "better": 1, "matchers": [{"string": "品質(命運卡):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_cards"]}}}
|
||||||
|
{"ref": "Quality (Elemental Damage Modifiers): #%", "better": 1, "matchers": [{"string": "品質(元素傷害詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_elemental_quality"]}}}
|
||||||
|
{"ref": "Quality (Life and Mana Modifiers): #%", "better": 1, "matchers": [{"string": "品質(生命和魔力詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_resource_quality"]}}}
|
||||||
|
{"ref": "Quality (Pack Size): #%", "better": 1, "matchers": [{"string": "品質(怪物群大小):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_pack_size"]}}}
|
||||||
|
{"ref": "Quality (Physical and Chaos Damage Modifiers): #%", "better": 1, "matchers": [{"string": "品質(物理和混沌傷害詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_physical_chaos_quality"]}}}
|
||||||
|
{"ref": "Quality (Rarity): #%", "better": 1, "matchers": [{"string": "品質(稀有度):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_rarity"]}}}
|
||||||
|
{"ref": "Quality (Resistance Modifiers): #%", "better": 1, "matchers": [{"string": "品質(抗性詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_resistance_quality"]}}}
|
||||||
|
{"ref": "Quality (Scarabs): #%", "better": 1, "matchers": [{"string": "品質(聖甲蟲):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_scarabs"]}}}
|
||||||
|
{"ref": "Quality (Speed Modifiers): #%", "better": 1, "matchers": [{"string": "品質(速度詞綴):#% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_speed_quality"]}}}
|
||||||
|
{"ref": "Reflection of Abyss (Difficulty #)", "better": 1, "matchers": [{"string": "深淵映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_38892"]}}}
|
||||||
|
{"ref": "Reflection of Ambush (Difficulty #)", "better": 1, "matchers": [{"string": "伏擊映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_48307"]}}}
|
||||||
|
{"ref": "Reflection of Angling (Difficulty #)", "better": 1, "matchers": [{"string": "釣魚映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_40794"]}}}
|
||||||
|
{"ref": "Reflection of Azurite (Difficulty #)", "better": 1, "matchers": [{"string": "碧藍映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_40031"]}}}
|
||||||
|
{"ref": "Reflection of Bestiary (Difficulty #)", "better": 1, "matchers": [{"string": "獸獵映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_55569"]}}}
|
||||||
|
{"ref": "Reflection of Breach (Difficulty #)", "better": 1, "matchers": [{"string": "裂痕映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_62572"]}}}
|
||||||
|
{"ref": "Reflection of Brutality (Difficulty #)", "better": 1, "matchers": [{"string": "殘暴映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_29096"]}}}
|
||||||
|
{"ref": "Reflection of Camaraderie (Difficulty #)", "better": 1, "matchers": [{"string": "友誼映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_35395"]}}}
|
||||||
|
{"ref": "Reflection of Catalysis (Difficulty #)", "better": 1, "matchers": [{"string": "催化映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_57850"]}}}
|
||||||
|
{"ref": "Reflection of Chaos (Difficulty #)", "better": 1, "matchers": [{"string": "混沌映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_50834"]}}}
|
||||||
|
{"ref": "Reflection of Conflict (Difficulty #)", "better": 1, "matchers": [{"string": "衝突映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_1931"]}}}
|
||||||
|
{"ref": "Reflection of Darkness (Difficulty #)", "better": 1, "matchers": [{"string": "黑暗映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_34457"]}}}
|
||||||
|
{"ref": "Reflection of Delirium (Difficulty #)", "better": 1, "matchers": [{"string": "譫妄映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_22138"]}}}
|
||||||
|
{"ref": "Reflection of Delve (Difficulty #)", "better": 1, "matchers": [{"string": "掘獄映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_18737"]}}}
|
||||||
|
{"ref": "Reflection of Demonfire (Difficulty #)", "better": 1, "matchers": [{"string": "業火映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_28500"]}}}
|
||||||
|
{"ref": "Reflection of Domination (Difficulty #)", "better": 1, "matchers": [{"string": "支配映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_63412"]}}}
|
||||||
|
{"ref": "Reflection of Entrapment (Difficulty #)", "better": 1, "matchers": [{"string": "誘捕映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_44399"]}}}
|
||||||
|
{"ref": "Reflection of Essence (Difficulty #)", "better": 1, "matchers": [{"string": "精髓映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_49862"]}}}
|
||||||
|
{"ref": "Reflection of Experimentation (Difficulty #)", "better": 1, "matchers": [{"string": "實驗映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_55676"]}}}
|
||||||
|
{"ref": "Reflection of Flame (Difficulty #)", "better": 1, "matchers": [{"string": "烈焰映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_42468"]}}}
|
||||||
|
{"ref": "Reflection of Fractured Dimensions (Difficulty #)", "better": 1, "matchers": [{"string": "破裂次元映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_49488"]}}}
|
||||||
|
{"ref": "Reflection of Frost (Difficulty #)", "better": 1, "matchers": [{"string": "寒霜映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_38110"]}}}
|
||||||
|
{"ref": "Reflection of Guilt (Difficulty #)", "better": 1, "matchers": [{"string": "責難映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_25480"]}}}
|
||||||
|
{"ref": "Reflection of Imprisonment (Difficulty #)", "better": 1, "matchers": [{"string": "監禁映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_10363"]}}}
|
||||||
|
{"ref": "Reflection of Kalandra (Difficulty #)", "better": 1, "matchers": [{"string": "卡蘭德映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_36591"]}}}
|
||||||
|
{"ref": "Reflection of Legion (Difficulty #)", "better": 1, "matchers": [{"string": "戰亂映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_403"]}}}
|
||||||
|
{"ref": "Reflection of Metamorph (Difficulty #)", "better": 1, "matchers": [{"string": "鍊魔映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_3699"]}}}
|
||||||
|
{"ref": "Reflection of Occultism (Difficulty #)", "better": 1, "matchers": [{"string": "神秘映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_24451"]}}}
|
||||||
|
{"ref": "Reflection of Paradise (Difficulty #)", "better": 1, "matchers": [{"string": "天堂映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_50846"]}}}
|
||||||
|
{"ref": "Reflection of Perverted Faith (Difficulty #)", "better": 1, "matchers": [{"string": "怪其信仰映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_27678"]}}}
|
||||||
|
{"ref": "Reflection of Phaaryl (Difficulty #)", "better": 1, "matchers": [{"string": "法瑞爾映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_7674"]}}}
|
||||||
|
{"ref": "Reflection of Possession (Difficulty #)", "better": 1, "matchers": [{"string": "附身映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_25049"]}}}
|
||||||
|
{"ref": "Reflection of Power (Difficulty #)", "better": 1, "matchers": [{"string": "權力映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_35950"]}}}
|
||||||
|
{"ref": "Reflection of Scourge (Difficulty #)", "better": 1, "matchers": [{"string": "災魘映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_62360"]}}}
|
||||||
|
{"ref": "Reflection of Stasis (Difficulty #)", "better": 1, "matchers": [{"string": "靜止映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_32968"]}}}
|
||||||
|
{"ref": "Reflection of Sulphite (Difficulty #)", "better": 1, "matchers": [{"string": "硫酸映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_45086"]}}}
|
||||||
|
{"ref": "Reflection of the Black Scythe (Difficulty #)", "better": 1, "matchers": [{"string": "黑暗血鐮映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_9662"]}}}
|
||||||
|
{"ref": "Reflection of the Breachlord (Difficulty #)", "better": 1, "matchers": [{"string": "裂痕君主映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_62935"]}}}
|
||||||
|
{"ref": "Reflection of the Broken Circle (Difficulty #)", "better": 1, "matchers": [{"string": "破碎環映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_43128"]}}}
|
||||||
|
{"ref": "Reflection of the Chalice (Difficulty #)", "better": 1, "matchers": [{"string": "聖杯映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_64561"]}}}
|
||||||
|
{"ref": "Reflection of the Chasm (Difficulty #)", "better": 1, "matchers": [{"string": "裂口映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_57101"]}}}
|
||||||
|
{"ref": "Reflection of the Dream (Difficulty #)", "better": 1, "matchers": [{"string": "夢想映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_27117"]}}}
|
||||||
|
{"ref": "Reflection of the Harbingers (Difficulty #)", "better": 1, "matchers": [{"string": "神諭映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_37203"]}}}
|
||||||
|
{"ref": "Reflection of the Hunter (Difficulty #)", "better": 1, "matchers": [{"string": "獵人映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_18816"]}}}
|
||||||
|
{"ref": "Reflection of the Monolith (Difficulty #)", "better": 1, "matchers": [{"string": "石陣映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_34796"]}}}
|
||||||
|
{"ref": "Reflection of the Nightmare (Difficulty #)", "better": 1, "matchers": [{"string": "噩夢映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_24232"]}}}
|
||||||
|
{"ref": "Reflection of the Storm (Difficulty #)", "better": 1, "matchers": [{"string": "風暴映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_2745"]}}}
|
||||||
|
{"ref": "Reflection of the Sun (Difficulty #)", "better": 1, "matchers": [{"string": "豔陽映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_60034"]}}}
|
||||||
|
{"ref": "Reflection of the Trove (Difficulty #)", "better": 1, "matchers": [{"string": "寶庫映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_46772"]}}}
|
||||||
|
{"ref": "Reflection of the Wilderness (Difficulty #)", "better": 1, "matchers": [{"string": "荒野映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_29224"]}}}
|
||||||
|
{"ref": "Reflection of Thralldom (Difficulty #)", "better": 1, "matchers": [{"string": "奴役映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_26813"]}}}
|
||||||
|
{"ref": "Reflection of Torment (Difficulty #)", "better": 1, "matchers": [{"string": "磨難映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_53950"]}}}
|
||||||
|
{"ref": "Reflection of Tyranny (Difficulty #)", "better": 1, "matchers": [{"string": "暴政映像 (難度 #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_60981"]}}}
|
||||||
32
renderer/public/.DS_Store/vendor/pseudo-stats/cmn-Hant/pseudo_stats.ndjson
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{"ref": "# Life Regenerated per Second", "better": 1, "matchers": [{"string": "# 每秒生命回復 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_life_regen"]}}}
|
||||||
|
{"ref": "#% increased Burning Damage", "better": 1, "matchers": [{"string": "增加 #% 燃燒傷害"}, {"string": "減少 #% 燃燒傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_burning_damage"], "explicit": ["explicit.stat_1175385867"], "implicit": ["implicit.stat_1175385867"], "fractured": ["fractured.stat_1175385867"]}}}
|
||||||
|
{"ref": "#% increased Cold Damage", "better": 1, "matchers": [{"string": "增加 #% 冰冷傷害"}, {"string": "減少 #% 冰冷傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_damage"], "explicit": ["explicit.stat_3291658075"], "implicit": ["implicit.stat_3291658075"], "fractured": ["fractured.stat_3291658075"], "scourge": ["scourge.stat_3291658075"], "crafted": ["crafted.stat_3291658075"]}}}
|
||||||
|
{"ref": "#% increased Cold Spell Damage", "better": 1, "matchers": [{"string": "增加 #% 冰冷法術傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Elemental Damage", "better": 1, "matchers": [{"string": "增加 #% 元素傷害"}, {"string": "有增加 #% 的元素傷害"}, {"string": "有減少 #% 的元素傷害", "negate": true}, {"string": "減少 #% 元素傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_elemental_damage"], "explicit": ["explicit.stat_3141070085"], "implicit": ["implicit.stat_3141070085"], "fractured": ["fractured.stat_3141070085"], "scourge": ["scourge.stat_3141070085"]}}}
|
||||||
|
{"ref": "#% increased Elemental Damage with Attack Skills", "better": 1, "matchers": [{"string": "攻擊技能增加 #% 元素傷害"}, {"string": "攻擊技能減少 #% 元素傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_elemental_damage_with_attack_skills"], "explicit": ["explicit.stat_387439868"], "implicit": ["implicit.stat_387439868"], "fractured": ["fractured.stat_387439868"], "scourge": ["scourge.stat_387439868"], "crafted": ["crafted.stat_387439868"]}}}
|
||||||
|
{"ref": "#% increased Fire Damage", "better": 1, "matchers": [{"string": "增加 #% 火焰傷害"}, {"string": "減少 #% 火焰傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_damage"], "explicit": ["explicit.stat_3962278098"], "implicit": ["implicit.stat_3962278098"], "fractured": ["fractured.stat_3962278098"], "scourge": ["scourge.stat_3962278098"], "crafted": ["crafted.stat_3962278098"]}}}
|
||||||
|
{"ref": "#% increased Fire Spell Damage", "better": 1, "matchers": [{"string": "增加 #% 火焰法術傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Lightning Damage", "better": 1, "matchers": [{"string": "增加 #% 閃電傷害"}, {"string": "減少 #% 閃電傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_damage"], "explicit": ["explicit.stat_2231156303"], "implicit": ["implicit.stat_2231156303"], "fractured": ["fractured.stat_2231156303"], "scourge": ["scourge.stat_2231156303"], "crafted": ["crafted.stat_2231156303"]}}}
|
||||||
|
{"ref": "#% increased Lightning Spell Damage", "better": 1, "matchers": [{"string": "增加 #% 閃電法術傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Mana Regeneration Rate", "better": 1, "matchers": [{"string": "增加 #% 魔力回復率"}, {"string": "減少 #% 魔力回復率", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_mana_regen"], "explicit": ["explicit.stat_789117908"], "implicit": ["implicit.stat_789117908"], "fractured": ["fractured.stat_789117908"], "scourge": ["scourge.stat_789117908"], "crafted": ["crafted.stat_789117908"]}}}
|
||||||
|
{"ref": "#% increased Movement Speed", "better": 1, "matchers": [{"string": "增加 #% 移動速度"}, {"string": "減少 #% 移動速度", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_movement_speed"], "explicit": ["explicit.stat_2250533757"], "implicit": ["implicit.stat_2250533757"], "fractured": ["fractured.stat_2250533757"], "enchant": ["enchant.stat_2250533757"], "scourge": ["scourge.stat_2250533757"], "crafted": ["crafted.stat_2250533757"]}}}
|
||||||
|
{"ref": "#% increased Spell Damage", "better": 1, "matchers": [{"string": "增加 #% 法術傷害"}, {"string": "減少 #% 法術傷害", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_spell_damage"], "explicit": ["explicit.stat_2974417149"], "implicit": ["implicit.stat_2974417149"], "fractured": ["fractured.stat_2974417149"], "enchant": ["enchant.stat_2974417149"], "scourge": ["scourge.stat_2974417149"], "crafted": ["crafted.stat_2974417149"]}}}
|
||||||
|
{"ref": "#% of Physical Attack Damage Leeched as Life", "dp": true, "better": 1, "matchers": [{"string": "#% 的物理攻擊傷害偷取生命"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_physical_attack_damage_leeched_as_life"], "explicit": ["explicit.stat_3593843976", "explicit.stat_55876295"], "implicit": ["implicit.stat_3593843976", "implicit.stat_55876295"], "fractured": ["fractured.stat_3593843976", "fractured.stat_55876295"], "scourge": ["scourge.stat_3593843976"], "crafted": ["crafted.stat_3593843976", "crafted.stat_55876295"]}}}
|
||||||
|
{"ref": "#% of Physical Attack Damage Leeched as Mana", "dp": true, "better": 1, "matchers": [{"string": "#% 物理攻擊傷害偷取魔力"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_physical_attack_damage_leeched_as_mana"], "explicit": ["explicit.stat_3237948413", "explicit.stat_669069897"], "implicit": ["implicit.stat_3237948413", "implicit.stat_669069897"], "fractured": ["fractured.stat_3237948413", "fractured.stat_669069897"], "scourge": ["scourge.stat_3237948413"], "crafted": ["crafted.stat_3237948413", "crafted.stat_669069897"]}}}
|
||||||
|
{"ref": "#% total increased Physical Damage", "better": 1, "matchers": [{"string": "增加 #% 物裡傷害 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_physical_damage"]}}}
|
||||||
|
{"ref": "+# total maximum Energy Shield", "better": 1, "matchers": [{"string": "+# 最大能量護盾 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_energy_shield"]}}}
|
||||||
|
{"ref": "+# total maximum Life", "better": 1, "matchers": [{"string": "+# 最大生命 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_life"]}}}
|
||||||
|
{"ref": "+# total maximum Mana", "better": 1, "matchers": [{"string": "+# 最大魔力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_mana"]}}}
|
||||||
|
{"ref": "+# total to all Attributes", "better": 1, "matchers": [{"string": "+# 全能力 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_all_attributes"]}}}
|
||||||
|
{"ref": "+# total to Dexterity", "better": 1, "matchers": [{"string": "+# 敏捷 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_dexterity"]}}}
|
||||||
|
{"ref": "+# total to Intelligence", "better": 1, "matchers": [{"string": "+# 智慧 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_intelligence"]}}}
|
||||||
|
{"ref": "+# total to Strength", "better": 1, "matchers": [{"string": "+# 力量 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_strength"]}}}
|
||||||
|
{"ref": "+#% Global Critical Strike Chance", "better": 1, "matchers": [{"string": "+#% 全域暴擊機率 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_global_critical_strike_chance"]}}}
|
||||||
|
{"ref": "+#% Global Critical Strike Multiplier", "better": 1, "matchers": [{"string": "+#% 全域暴擊加成 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_global_critical_strike_multiplier"]}}}
|
||||||
|
{"ref": "+#% total Attack Speed", "better": 1, "matchers": [{"string": "+#% 攻擊速度 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_attack_speed"]}}}
|
||||||
|
{"ref": "+#% total Cast Speed", "better": 1, "matchers": [{"string": "+#% 施放速度 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_cast_speed"]}}}
|
||||||
|
{"ref": "+#% total Elemental Resistance", "better": 1, "matchers": [{"string": "+#% 元素抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_elemental_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Chaos Resistance", "better": 1, "matchers": [{"string": "+#% 總混沌抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_chaos_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Cold Resistance", "better": 1, "matchers": [{"string": "+#% 冰冷抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_cold_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Fire Resistance", "better": 1, "matchers": [{"string": "+#% 火焰抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_fire_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Lightning Resistance", "better": 1, "matchers": [{"string": "+#% 閃電抗性 "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_lightning_resistance"]}}}
|
||||||
292
renderer/public/.DS_Store/vendor/pseudo-stats/en/all-pseudo.ndjson
vendored
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
{"ref": "# Crafted Modifiers", "better": 1, "matchers": [{"string": "# Crafted Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_crafted_mods"]}}}
|
||||||
|
{"ref": "# Crafted Prefix Modifiers", "better": 1, "matchers": [{"string": "# Crafted Prefix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_crafted_prefix_mods"]}}}
|
||||||
|
{"ref": "# Crafted Suffix Modifiers", "better": 1, "matchers": [{"string": "# Crafted Suffix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_crafted_suffix_mods"]}}}
|
||||||
|
{"ref": "# Empty Modifiers", "better": 1, "matchers": [{"string": "# Empty Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_empty_affix_mods"]}}}
|
||||||
|
{"ref": "# Empty Prefix Modifiers", "better": 1, "matchers": [{"string": "# Empty Prefix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_empty_prefix_mods"]}}}
|
||||||
|
{"ref": "# Empty Suffix Modifiers", "better": 1, "matchers": [{"string": "# Empty Suffix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_empty_suffix_mods"]}}}
|
||||||
|
{"ref": "# Enchant Modifiers", "better": 1, "matchers": [{"string": "# Enchant Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_enchant_mods"]}}}
|
||||||
|
{"ref": "# Fractured Modifiers", "better": 1, "matchers": [{"string": "# Fractured Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_fractured_mods"]}}}
|
||||||
|
{"ref": "# Implicit Modifiers", "better": 1, "matchers": [{"string": "# Implicit Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_implicit_mods"]}}}
|
||||||
|
{"ref": "# Life Regenerated per Second", "better": 1, "matchers": [{"string": "# Life Regenerated per Second "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_life_regen"]}}}
|
||||||
|
{"ref": "# Modifiers", "better": 1, "matchers": [{"string": "# Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_affix_mods"]}}}
|
||||||
|
{"ref": "# Notable Passive Skills", "better": 1, "matchers": [{"string": "# Notable Passive Skills "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_notable_passive_skills"]}}}
|
||||||
|
{"ref": "# Prefix Modifiers", "better": 1, "matchers": [{"string": "# Prefix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_prefix_mods"]}}}
|
||||||
|
{"ref": "# Suffix Modifiers", "better": 1, "matchers": [{"string": "# Suffix Modifiers "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_number_of_suffix_mods"]}}}
|
||||||
|
{"ref": "# total Elemental Resistances", "better": 1, "matchers": [{"string": "# total Elemental Resistances "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_count_elemental_resistances"]}}}
|
||||||
|
{"ref": "# total Resistances", "better": 1, "matchers": [{"string": "# total Resistances "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_count_resistances"]}}}
|
||||||
|
{"ref": "#% Base Defence Percentile", "better": 1, "matchers": [{"string": "#% Base Defence Percentile "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_base_defence_percentile"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Atlas Memories", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Atlas Memories "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_memory_line"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Conqueror Maps", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Conqueror Maps "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_conqueror_map"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Elder Maps", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Elder Maps "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_elder_map"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Maven Invitations", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Maven Invitations "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_maven_invitation"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Scarabs", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Scarabs "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_scarab"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Shaper Maps", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Shaper Maps "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_shaper_map"]}}}
|
||||||
|
{"ref": "#% chance for dropped Maps to convert to Unique Maps", "better": 1, "matchers": [{"string": "#% chance for dropped Maps to convert to Unique Maps "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_conversion_unique_map"]}}}
|
||||||
|
{"ref": "#% increased Burning Damage", "better": 1, "matchers": [{"string": "#% increased Burning Damage"}, {"string": "#% reduced Burning Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_burning_damage"], "explicit": ["explicit.stat_1175385867"], "implicit": ["implicit.stat_1175385867"], "fractured": ["fractured.stat_1175385867"]}}}
|
||||||
|
{"ref": "#% increased Cold Damage", "better": 1, "matchers": [{"string": "#% increased Cold Damage"}, {"string": "#% reduced Cold Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_damage"], "explicit": ["explicit.stat_3291658075"], "implicit": ["implicit.stat_3291658075"], "fractured": ["fractured.stat_3291658075"], "scourge": ["scourge.stat_3291658075"], "crafted": ["crafted.stat_3291658075"]}}}
|
||||||
|
{"ref": "#% increased Cold Damage with Attack Skills", "better": 1, "matchers": [{"string": "#% increased Cold Damage with Attack Skills"}, {"string": "#% reduced Cold Damage with Attack Skills", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_damage_with_attack_skills"], "explicit": ["explicit.stat_860668586"], "implicit": ["implicit.stat_860668586"]}}}
|
||||||
|
{"ref": "#% increased Cold Spell Damage", "better": 1, "matchers": [{"string": "#% increased Cold Spell Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_cold_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Elemental Damage", "better": 1, "matchers": [{"string": "#% increased Elemental Damage"}, {"string": "Has #% increased Elemental Damage"}, {"string": "#% reduced Elemental Damage", "negate": true}, {"string": "Has #% reduced Elemental Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_elemental_damage"], "explicit": ["explicit.stat_3141070085"], "implicit": ["implicit.stat_3141070085"], "fractured": ["fractured.stat_3141070085"], "enchant": ["enchant.stat_692420067"], "scourge": ["scourge.stat_3141070085"]}}}
|
||||||
|
{"ref": "#% increased Elemental Damage with Attack Skills", "better": 1, "matchers": [{"string": "#% increased Elemental Damage with Attack Skills"}, {"string": "#% reduced Elemental Damage with Attack Skills", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_elemental_damage_with_attack_skills"], "explicit": ["explicit.stat_387439868"], "implicit": ["implicit.stat_387439868"], "fractured": ["fractured.stat_387439868"], "scourge": ["scourge.stat_387439868"], "crafted": ["crafted.stat_387439868"]}}}
|
||||||
|
{"ref": "#% increased Fire Damage", "better": 1, "matchers": [{"string": "#% increased Fire Damage"}, {"string": "#% reduced Fire Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_damage"], "explicit": ["explicit.stat_3962278098"], "implicit": ["implicit.stat_3962278098"], "fractured": ["fractured.stat_3962278098"], "scourge": ["scourge.stat_3962278098"], "crafted": ["crafted.stat_3962278098"]}}}
|
||||||
|
{"ref": "#% increased Fire Damage with Attack Skills", "better": 1, "matchers": [{"string": "#% increased Fire Damage with Attack Skills"}, {"string": "#% reduced Fire Damage with Attack Skills", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_damage_with_attack_skills"], "implicit": ["implicit.stat_2468413380"]}}}
|
||||||
|
{"ref": "#% increased Fire Spell Damage", "better": 1, "matchers": [{"string": "#% increased Fire Spell Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_fire_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Lightning Damage", "better": 1, "matchers": [{"string": "#% increased Lightning Damage"}, {"string": "#% reduced Lightning Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_damage"], "explicit": ["explicit.stat_2231156303"], "implicit": ["implicit.stat_2231156303"], "fractured": ["fractured.stat_2231156303"], "scourge": ["scourge.stat_2231156303"], "crafted": ["crafted.stat_2231156303"]}}}
|
||||||
|
{"ref": "#% increased Lightning Damage with Attack Skills", "better": 1, "matchers": [{"string": "#% increased Lightning Damage with Attack Skills"}, {"string": "#% reduced Lightning Damage with Attack Skills", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_damage_with_attack_skills"], "explicit": ["explicit.stat_4208907162"], "implicit": ["implicit.stat_4208907162"]}}}
|
||||||
|
{"ref": "#% increased Lightning Spell Damage", "better": 1, "matchers": [{"string": "#% increased Lightning Spell Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_lightning_spell_damage"]}}}
|
||||||
|
{"ref": "#% increased Mana Regeneration Rate", "better": 1, "matchers": [{"string": "#% increased Mana Regeneration Rate"}, {"string": "#% reduced Mana Regeneration Rate", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_mana_regen"], "explicit": ["explicit.stat_789117908"], "implicit": ["implicit.stat_789117908"], "fractured": ["fractured.stat_789117908"], "scourge": ["scourge.stat_789117908"], "crafted": ["crafted.stat_789117908"]}}}
|
||||||
|
{"ref": "#% increased Movement Speed", "better": 1, "matchers": [{"string": "#% increased Movement Speed"}, {"string": "#% reduced Movement Speed", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_movement_speed"], "explicit": ["explicit.stat_2250533757"], "implicit": ["implicit.stat_2250533757"], "fractured": ["fractured.stat_2250533757"], "enchant": ["enchant.stat_2250533757"], "scourge": ["scourge.stat_2250533757"], "crafted": ["crafted.stat_2250533757"]}}}
|
||||||
|
{"ref": "#% increased Rarity of Items found", "better": 1, "matchers": [{"string": "#% increased Rarity of Items found"}, {"string": "#% reduced Rarity of Items found", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_rarity"], "explicit": ["explicit.stat_3917489142"], "implicit": ["implicit.stat_3917489142"], "fractured": ["fractured.stat_3917489142"], "scourge": ["scourge.stat_3917489142"], "crafted": ["crafted.stat_3917489142"]}}}
|
||||||
|
{"ref": "#% increased Spell Damage", "better": 1, "matchers": [{"string": "#% increased Spell Damage"}, {"string": "#% reduced Spell Damage", "negate": true}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_spell_damage"], "explicit": ["explicit.stat_2974417149"], "implicit": ["implicit.stat_2974417149"], "fractured": ["fractured.stat_2974417149"], "enchant": ["enchant.stat_2974417149"], "scourge": ["scourge.stat_2974417149"], "crafted": ["crafted.stat_2974417149"]}}}
|
||||||
|
{"ref": "#% of Life Regenerated per Second", "better": 1, "matchers": [{"string": "#% of Life Regenerated per Second "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_percent_life_regen"]}}}
|
||||||
|
{"ref": "#% of Physical Attack Damage Leeched as Life", "dp": true, "better": 1, "matchers": [{"string": "#% of Physical Attack Damage Leeched as Life"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_physical_attack_damage_leeched_as_life"], "explicit": ["explicit.stat_3593843976", "explicit.stat_55876295"], "implicit": ["implicit.stat_3593843976", "implicit.stat_55876295"], "fractured": ["fractured.stat_3593843976", "fractured.stat_55876295"], "scourge": ["scourge.stat_3593843976"], "crafted": ["crafted.stat_3593843976", "crafted.stat_55876295"]}}}
|
||||||
|
{"ref": "#% of Physical Attack Damage Leeched as Mana", "dp": true, "better": 1, "matchers": [{"string": "#% of Physical Attack Damage Leeched as Mana"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_physical_attack_damage_leeched_as_mana"], "explicit": ["explicit.stat_3237948413", "explicit.stat_669069897"], "implicit": ["implicit.stat_3237948413", "implicit.stat_669069897"], "fractured": ["fractured.stat_3237948413", "fractured.stat_669069897"], "enchant": ["enchant.stat_669069897"], "scourge": ["scourge.stat_3237948413"], "crafted": ["crafted.stat_3237948413", "crafted.stat_669069897"]}}}
|
||||||
|
{"ref": "#% total increased maximum Energy Shield", "better": 1, "matchers": [{"string": "#% total increased maximum Energy Shield "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_energy_shield"]}}}
|
||||||
|
{"ref": "#% total increased Physical Damage", "better": 1, "matchers": [{"string": "#% total increased Physical Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_increased_physical_damage"]}}}
|
||||||
|
{"ref": "+# total maximum Energy Shield", "better": 1, "matchers": [{"string": "+# total maximum Energy Shield "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_energy_shield"]}}}
|
||||||
|
{"ref": "+# total maximum Life", "better": 1, "matchers": [{"string": "+# total maximum Life "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_life"]}}}
|
||||||
|
{"ref": "+# total maximum Mana", "better": 1, "matchers": [{"string": "+# total maximum Mana "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_mana"]}}}
|
||||||
|
{"ref": "+# total to all Attributes", "better": 1, "matchers": [{"string": "+# total to all Attributes "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_all_attributes"]}}}
|
||||||
|
{"ref": "+# total to Dexterity", "better": 1, "matchers": [{"string": "+# total to Dexterity "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_dexterity"]}}}
|
||||||
|
{"ref": "+# total to Intelligence", "better": 1, "matchers": [{"string": "+# total to Intelligence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_intelligence"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Aura Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Aura Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_aura_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Bow Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Bow Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_bow_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Chaos Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Chaos Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_chaos_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Cold Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Cold Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_cold_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Curse Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Curse Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_curse_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Dexterity Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Dexterity Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_dexterity_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Elemental Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Elemental Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_elemental_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Fire Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Fire Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_fire_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Golem Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Golem Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_golem_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Intelligence Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Intelligence Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_intelligence_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Lightning Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Lightning Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_lightning_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Melee Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Melee Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_melee_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Minion Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Minion Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_minion_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Movement Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Movement Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_movement_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Projectile Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Projectile Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_projectile_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Skill Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Skill Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_skill_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Spell Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Spell Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_spell_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Strength Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Strength Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_strength_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Support Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Support Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_support_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Vaal Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Vaal Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_vaal_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Level of Socketed Warcry Gems", "better": 1, "matchers": [{"string": "+# total to Level of Socketed Warcry Gems "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_additional_warcry_gem_levels"]}}}
|
||||||
|
{"ref": "+# total to Strength", "better": 1, "matchers": [{"string": "+# total to Strength "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_strength"]}}}
|
||||||
|
{"ref": "+#% Global Critical Strike Chance", "better": 1, "matchers": [{"string": "+#% Global Critical Strike Chance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_global_critical_strike_chance"]}}}
|
||||||
|
{"ref": "+#% Global Critical Strike Multiplier", "better": 1, "matchers": [{"string": "+#% Global Critical Strike Multiplier "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_global_critical_strike_multiplier"]}}}
|
||||||
|
{"ref": "+#% total Attack Speed", "better": 1, "matchers": [{"string": "+#% total Attack Speed "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_attack_speed"]}}}
|
||||||
|
{"ref": "+#% total Cast Speed", "better": 1, "matchers": [{"string": "+#% total Cast Speed "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_cast_speed"]}}}
|
||||||
|
{"ref": "+#% total Critical Strike Chance for Spells", "better": 1, "matchers": [{"string": "+#% total Critical Strike Chance for Spells "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_critical_strike_chance_for_spells"]}}}
|
||||||
|
{"ref": "+#% total Elemental Resistance", "better": 1, "matchers": [{"string": "+#% total Elemental Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_elemental_resistance"]}}}
|
||||||
|
{"ref": "+#% total Resistance", "better": 1, "matchers": [{"string": "+#% total Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_resistance"]}}}
|
||||||
|
{"ref": "+#% total to all Elemental Resistances", "better": 1, "matchers": [{"string": "+#% total to all Elemental Resistances "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_all_elemental_resistances"]}}}
|
||||||
|
{"ref": "+#% total to Chaos Resistance", "better": 1, "matchers": [{"string": "+#% total to Chaos Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_chaos_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Cold Resistance", "better": 1, "matchers": [{"string": "+#% total to Cold Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_cold_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Fire Resistance", "better": 1, "matchers": [{"string": "+#% total to Fire Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_fire_resistance"]}}}
|
||||||
|
{"ref": "+#% total to Lightning Resistance", "better": 1, "matchers": [{"string": "+#% total to Lightning Resistance "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_total_lightning_resistance"]}}}
|
||||||
|
{"ref": "Adds # to # Chaos Damage", "better": 1, "matchers": [{"string": "Adds # to # Chaos Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_chaos_damage"], "explicit": ["explicit.stat_2223678961", "explicit.stat_3531280422"], "implicit": ["implicit.stat_2223678961", "implicit.stat_3531280422"], "fractured": ["fractured.stat_2223678961"], "enchant": ["enchant.stat_2223678961"], "scourge": ["scourge.stat_2223678961"]}}}
|
||||||
|
{"ref": "Adds # to # Chaos Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Chaos Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_chaos_damage_to_attacks"], "explicit": ["explicit.stat_674553446"], "implicit": ["implicit.stat_674553446"], "fractured": ["fractured.stat_674553446"], "crafted": ["crafted.stat_674553446"]}}}
|
||||||
|
{"ref": "Adds # to # Chaos Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Chaos Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_chaos_damage_to_spells"], "explicit": ["explicit.stat_2300399854"], "implicit": ["implicit.stat_2300399854"], "fractured": ["fractured.stat_2300399854"]}}}
|
||||||
|
{"ref": "Adds # to # Cold Damage", "better": 1, "matchers": [{"string": "Adds # to # Cold Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_cold_damage"], "explicit": ["explicit.stat_1037193709", "explicit.stat_2387423236"], "implicit": ["implicit.stat_1037193709", "implicit.stat_2387423236"], "fractured": ["fractured.stat_1037193709", "fractured.stat_2387423236"], "enchant": ["enchant.stat_1037193709"], "scourge": ["scourge.stat_1037193709"], "crafted": ["crafted.stat_1037193709", "crafted.stat_2387423236"]}}}
|
||||||
|
{"ref": "Adds # to # Cold Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Cold Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_cold_damage_to_attacks"], "explicit": ["explicit.stat_4067062424"], "implicit": ["implicit.stat_4067062424"], "fractured": ["fractured.stat_4067062424"], "crafted": ["crafted.stat_4067062424"]}}}
|
||||||
|
{"ref": "Adds # to # Cold Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Cold Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_cold_damage_to_spells"], "explicit": ["explicit.stat_2469416729"], "implicit": ["implicit.stat_2469416729"], "fractured": ["fractured.stat_2469416729"], "scourge": ["scourge.stat_2469416729"], "crafted": ["crafted.stat_2469416729"]}}}
|
||||||
|
{"ref": "Adds # to # Damage", "better": 1, "matchers": [{"string": "Adds # to # Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_damage"]}}}
|
||||||
|
{"ref": "Adds # to # Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Damage to Attacks "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_damage_to_attacks"]}}}
|
||||||
|
{"ref": "Adds # to # Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Damage to Spells "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_damage_to_spells"]}}}
|
||||||
|
{"ref": "Adds # to # Elemental Damage", "better": 1, "matchers": [{"string": "Adds # to # Elemental Damage "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_elemental_damage"]}}}
|
||||||
|
{"ref": "Adds # to # Elemental Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Elemental Damage to Attacks "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_elemental_damage_to_attacks"]}}}
|
||||||
|
{"ref": "Adds # to # Elemental Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Elemental Damage to Spells "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_elemental_damage_to_spells"]}}}
|
||||||
|
{"ref": "Adds # to # Fire Damage", "better": 1, "matchers": [{"string": "Adds # to # Fire Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_fire_damage"], "explicit": ["explicit.stat_321077055", "explicit.stat_709508406"], "implicit": ["implicit.stat_321077055", "implicit.stat_709508406"], "fractured": ["fractured.stat_321077055", "fractured.stat_709508406"], "enchant": ["enchant.stat_709508406"], "scourge": ["scourge.stat_709508406"], "crafted": ["crafted.stat_321077055", "crafted.stat_709508406"]}}}
|
||||||
|
{"ref": "Adds # to # Fire Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Fire Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_fire_damage_to_attacks"], "explicit": ["explicit.stat_1573130764"], "implicit": ["implicit.stat_1573130764"], "fractured": ["fractured.stat_1573130764"], "crafted": ["crafted.stat_1573130764"]}}}
|
||||||
|
{"ref": "Adds # to # Fire Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Fire Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_fire_damage_to_spells"], "explicit": ["explicit.stat_1133016593"], "implicit": ["implicit.stat_1133016593"], "fractured": ["fractured.stat_1133016593"], "scourge": ["scourge.stat_1133016593"], "crafted": ["crafted.stat_1133016593"]}}}
|
||||||
|
{"ref": "Adds # to # Lightning Damage", "better": 1, "matchers": [{"string": "Adds # to # Lightning Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_lightning_damage"], "explicit": ["explicit.stat_1334060246", "explicit.stat_3336890334"], "implicit": ["implicit.stat_1334060246", "implicit.stat_3336890334"], "fractured": ["fractured.stat_1334060246", "fractured.stat_3336890334"], "enchant": ["enchant.stat_3336890334"], "scourge": ["scourge.stat_3336890334"], "crafted": ["crafted.stat_1334060246", "crafted.stat_3336890334"]}}}
|
||||||
|
{"ref": "Adds # to # Lightning Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Lightning Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_lightning_damage_to_attacks"], "explicit": ["explicit.stat_1754445556"], "implicit": ["implicit.stat_1754445556"], "fractured": ["fractured.stat_1754445556"], "crafted": ["crafted.stat_1754445556"]}}}
|
||||||
|
{"ref": "Adds # to # Lightning Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Lightning Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_lightning_damage_to_spells"], "explicit": ["explicit.stat_2831165374"], "implicit": ["implicit.stat_2831165374"], "fractured": ["fractured.stat_2831165374"], "scourge": ["scourge.stat_2831165374"], "crafted": ["crafted.stat_2831165374"]}}}
|
||||||
|
{"ref": "Adds # to # Physical Damage", "better": 1, "matchers": [{"string": "Adds # to # Physical Damage"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_physical_damage"], "explicit": ["explicit.stat_1940865751", "explicit.stat_960081730"], "implicit": ["implicit.stat_1940865751"], "fractured": ["fractured.stat_1940865751", "fractured.stat_960081730"], "scourge": ["scourge.stat_1940865751"], "crafted": ["crafted.stat_1940865751"]}}}
|
||||||
|
{"ref": "Adds # to # Physical Damage to Attacks", "better": 1, "matchers": [{"string": "Adds # to # Physical Damage to Attacks"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_physical_damage_to_attacks"], "explicit": ["explicit.stat_3032590688"], "implicit": ["implicit.stat_3032590688"], "fractured": ["fractured.stat_3032590688"], "crafted": ["crafted.stat_3032590688"]}}}
|
||||||
|
{"ref": "Adds # to # Physical Damage to Spells", "better": 1, "matchers": [{"string": "Adds # to # Physical Damage to Spells"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_adds_physical_damage_to_spells"], "explicit": ["explicit.stat_2435536961"], "implicit": ["implicit.stat_2435536961"], "fractured": ["fractured.stat_2435536961"], "scourge": ["scourge.stat_2435536961"]}}}
|
||||||
|
{"ref": "Has # Influences", "better": 1, "matchers": [{"string": "Has # Influences "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_influence_count"]}}}
|
||||||
|
{"ref": "Has Crusader Influence", "better": 1, "matchers": [{"string": "Has Crusader Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_crusader_influence"]}}}
|
||||||
|
{"ref": "Has Elder Influence", "better": 1, "matchers": [{"string": "Has Elder Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_elder_influence"]}}}
|
||||||
|
{"ref": "Has Hunter Influence", "better": 1, "matchers": [{"string": "Has Hunter Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_hunter_influence"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Battleground Graves", "better": 1, "matchers": [{"string": "Has Logbook Area: Battleground Graves "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_battleground_graves"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Bluffs", "better": 1, "matchers": [{"string": "Has Logbook Area: Bluffs "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_bluffs"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Cemetery", "better": 1, "matchers": [{"string": "Has Logbook Area: Cemetery "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_cemetery"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Desert Ruins", "better": 1, "matchers": [{"string": "Has Logbook Area: Desert Ruins "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_desert_ruins"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Dried Riverbed", "better": 1, "matchers": [{"string": "Has Logbook Area: Dried Riverbed "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_dried_riverbed"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Forest Ruins", "better": 1, "matchers": [{"string": "Has Logbook Area: Forest Ruins "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_forest_ruins"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Karui Wargraves", "better": 1, "matchers": [{"string": "Has Logbook Area: Karui Wargraves "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_karui_wargraves"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Mountainside", "better": 1, "matchers": [{"string": "Has Logbook Area: Mountainside "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_mountainside"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Rotting Temple", "better": 1, "matchers": [{"string": "Has Logbook Area: Rotting Temple "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_rotting_temple"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Sarn Slums", "better": 1, "matchers": [{"string": "Has Logbook Area: Sarn Slums "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_sarn_slums"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Scrublands", "better": 1, "matchers": [{"string": "Has Logbook Area: Scrublands "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_scrublands"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Shipwreck Reef", "better": 1, "matchers": [{"string": "Has Logbook Area: Shipwreck Reef "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_shipwreck_reef"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Utzaal Outskirts", "better": 1, "matchers": [{"string": "Has Logbook Area: Utzaal Outskirts "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_utzaal_outskirts"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Vaal Temple", "better": 1, "matchers": [{"string": "Has Logbook Area: Vaal Temple "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_vaal_temple"]}}}
|
||||||
|
{"ref": "Has Logbook Area: Volcanic Island", "better": 1, "matchers": [{"string": "Has Logbook Area: Volcanic Island "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_area_volcano"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Black Scythe Mercenaries", "better": 0, "matchers": [{"string": "Black Scythe Mercenaries"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_mercenaries"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Druids of the Broken Circle", "better": 0, "matchers": [{"string": "Druids of the Broken Circle"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_druids"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Knights of the Sun", "better": 0, "matchers": [{"string": "Knights of the Sun"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_knights"]}}}
|
||||||
|
{"ref": "Has Logbook Faction: Order of the Chalice", "better": 0, "matchers": [{"string": "Order of the Chalice"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_logbook_faction_order"]}}}
|
||||||
|
{"ref": "Has Redeemer Influence", "better": 1, "matchers": [{"string": "Has Redeemer Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_redeemer_influence"]}}}
|
||||||
|
{"ref": "Has Room: Antechamber", "better": 0, "matchers": [{"string": "Antechamber"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_antechamber"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Apex of Ascension (Tier 3)", "better": 0, "matchers": [{"string": "Apex of Ascension (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_sacrifice_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Apex of Atzoatl", "better": 0, "matchers": [{"string": "Apex of Atzoatl"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_apex"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Arena of Valour (Tier 2)", "better": 0, "matchers": [{"string": "Arena of Valour (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_weapon_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Armourer's Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Armourer's Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_armour_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Armoury (Tier 2)", "better": 0, "matchers": [{"string": "Armoury (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_armour_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Atlas of Worlds (Tier 3)", "better": 0, "matchers": [{"string": "Atlas of Worlds (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cartography_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Automaton Lab (Tier 2)", "better": 0, "matchers": [{"string": "Automaton Lab (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_minions_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Banquet Hall", "better": 0, "matchers": [{"string": "Banquet Hall"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_banquet_hall"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Barracks (Tier 2)", "better": 0, "matchers": [{"string": "Barracks (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breeding_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Breach Containment Chamber (Tier 2)", "better": 0, "matchers": [{"string": "Breach Containment Chamber (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breach_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Catalyst of Corruption (Tier 2)", "better": 0, "matchers": [{"string": "Catalyst of Corruption (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_corruption_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Cellar", "better": 0, "matchers": [{"string": "Cellar"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cellar"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Chamber of Iron (Tier 3)", "better": 0, "matchers": [{"string": "Chamber of Iron (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_armour_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Chasm", "better": 0, "matchers": [{"string": "Chasm"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chasm_room"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Cloister", "better": 0, "matchers": [{"string": "Cloister"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cloister"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Conduit of Lightning (Tier 3)", "better": 0, "matchers": [{"string": "Conduit of Lightning (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_lightning_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Corruption Chamber (Tier 1)", "better": 0, "matchers": [{"string": "Corruption Chamber (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_corruption_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Court of Sealed Death (Tier 3)", "better": 0, "matchers": [{"string": "Court of Sealed Death (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_strongbox_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Crucible of Flame (Tier 3)", "better": 0, "matchers": [{"string": "Crucible of Flame (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_fire_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Cultivar Chamber (Tier 2)", "better": 0, "matchers": [{"string": "Cultivar Chamber (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_poison_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Defense Research Lab (Tier 3)", "better": 0, "matchers": [{"string": "Defense Research Lab (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trap_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Demolition Lab (Tier 2)", "better": 0, "matchers": [{"string": "Demolition Lab (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_explosives_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Department of Thaumaturgy (Tier 2)", "better": 0, "matchers": [{"string": "Department of Thaumaturgy (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_gem_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Doryani's Institute (Tier 3)", "better": 0, "matchers": [{"string": "Doryani's Institute (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_gem_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Engineering Department (Tier 2)", "better": 0, "matchers": [{"string": "Engineering Department (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_workshop_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Explosives Room (Tier 1)", "better": 0, "matchers": [{"string": "Explosives Room (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_explosives_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Factory (Tier 3)", "better": 0, "matchers": [{"string": "Factory (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_workshop_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Flame Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Flame Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_fire_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Gemcutter's Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Gemcutter's Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_gem_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Glittering Halls (Tier 3)", "better": 0, "matchers": [{"string": "Glittering Halls (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trinket_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Guardhouse (Tier 1)", "better": 0, "matchers": [{"string": "Guardhouse (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breeding_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Champions (Tier 3)", "better": 0, "matchers": [{"string": "Hall of Champions (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_weapon_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Heroes (Tier 2)", "better": 0, "matchers": [{"string": "Hall of Heroes (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_legion_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Legends (Tier 3)", "better": 0, "matchers": [{"string": "Hall of Legends (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_legion_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Locks (Tier 2)", "better": 0, "matchers": [{"string": "Hall of Locks (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_strongbox_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Lords (Tier 2)", "better": 0, "matchers": [{"string": "Hall of Lords (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_queens_chambers_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Mettle (Tier 1)", "better": 0, "matchers": [{"string": "Hall of Mettle (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_legion_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of Offerings (Tier 2)", "better": 0, "matchers": [{"string": "Hall of Offerings (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_sacrifice_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hall of War (Tier 3)", "better": 0, "matchers": [{"string": "Hall of War (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breeding_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Halls", "better": 0, "matchers": [{"string": "Halls"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_halls"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hatchery (Tier 1)", "better": 0, "matchers": [{"string": "Hatchery (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_minions_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: House of the Others (Tier 3)", "better": 0, "matchers": [{"string": "House of the Others (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breach_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hurricane Engine (Tier 2)", "better": 0, "matchers": [{"string": "Hurricane Engine (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_storm_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Hybridisation Chamber (Tier 3)", "better": 0, "matchers": [{"string": "Hybridisation Chamber (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_minions_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Jeweller's Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Jeweller's Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trinket_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Jewellery Forge (Tier 2)", "better": 0, "matchers": [{"string": "Jewellery Forge (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trinket_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Lightning Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Lightning Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_lightning_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Locus of Corruption (Tier 3)", "better": 0, "matchers": [{"string": "Locus of Corruption (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_corruption_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Museum of Artefacts (Tier 3)", "better": 0, "matchers": [{"string": "Museum of Artefacts (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chests_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Office of Cartography (Tier 2)", "better": 0, "matchers": [{"string": "Office of Cartography (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cartography_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Omnitect Forge (Tier 2)", "better": 0, "matchers": [{"string": "Omnitect Forge (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_fire_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Omnitect Reactor Plant (Tier 2)", "better": 0, "matchers": [{"string": "Omnitect Reactor Plant (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_boss_lightning_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Passageways", "better": 0, "matchers": [{"string": "Passageways"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_passageways"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Pits", "better": 0, "matchers": [{"string": "Pits"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_the_pits"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Poison Garden (Tier 1)", "better": 0, "matchers": [{"string": "Poison Garden (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_poison_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Pools of Restoration (Tier 1)", "better": 0, "matchers": [{"string": "Pools of Restoration (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_healing_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Royal Meeting Room (Tier 1)", "better": 0, "matchers": [{"string": "Royal Meeting Room (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_queens_chambers_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sacrificial Chamber (Tier 1)", "better": 0, "matchers": [{"string": "Sacrificial Chamber (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_sacrifice_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sadist's Den (Tier 3)", "better": 0, "matchers": [{"string": "Sadist's Den (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_torment_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sanctum of Immortality (Tier 3)", "better": 0, "matchers": [{"string": "Sanctum of Immortality (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_healing_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sanctum of Unity (Tier 2)", "better": 0, "matchers": [{"string": "Sanctum of Unity (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_empowering_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sanctum of Vitality (Tier 2)", "better": 0, "matchers": [{"string": "Sanctum of Vitality (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_healing_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Shrine of Empowerment (Tier 1)", "better": 0, "matchers": [{"string": "Shrine of Empowerment (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_empowering_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Shrine of Unmaking (Tier 3)", "better": 0, "matchers": [{"string": "Shrine of Unmaking (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_explosives_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Sparring Room (Tier 1)", "better": 0, "matchers": [{"string": "Sparring Room (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_weapon_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Splinter Research Lab (Tier 1)", "better": 0, "matchers": [{"string": "Splinter Research Lab (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_breach_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Storage Room (Tier 1)", "better": 0, "matchers": [{"string": "Storage Room (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chests_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Storm of Corruption (Tier 3)", "better": 0, "matchers": [{"string": "Storm of Corruption (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_storm_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Strongbox Chamber (Tier 1)", "better": 0, "matchers": [{"string": "Strongbox Chamber (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_strongbox_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Surveyor's Study (Tier 1)", "better": 0, "matchers": [{"string": "Surveyor's Study (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_cartography_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Tempest Generator (Tier 1)", "better": 0, "matchers": [{"string": "Tempest Generator (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_storm_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Temple Defense Workshop (Tier 2)", "better": 0, "matchers": [{"string": "Temple Defense Workshop (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trap_room_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Temple Nexus (Tier 3)", "better": 0, "matchers": [{"string": "Temple Nexus (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_empowering_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Throne of Atziri (Tier 3)", "better": 0, "matchers": [{"string": "Throne of Atziri (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_queens_chambers_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Tombs", "better": 0, "matchers": [{"string": "Tombs"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_tombs"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Torment Cells (Tier 1)", "better": 0, "matchers": [{"string": "Torment Cells (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_torment_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Torture Cages (Tier 2)", "better": 0, "matchers": [{"string": "Torture Cages (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_torment_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Toxic Grove (Tier 3)", "better": 0, "matchers": [{"string": "Toxic Grove (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_poison_room_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Trap Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Trap Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_trap_room_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Treasury (Tier 2)", "better": 0, "matchers": [{"string": "Treasury (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_currency_vault_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Tunnels", "better": 0, "matchers": [{"string": "Tunnels"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_tunnels"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Vault (Tier 1)", "better": 0, "matchers": [{"string": "Vault (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_currency_vault_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Warehouses (Tier 2)", "better": 0, "matchers": [{"string": "Warehouses (Tier 2)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_chests_2"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Wealth of the Vaal (Tier 3)", "better": 0, "matchers": [{"string": "Wealth of the Vaal (Tier 3)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_currency_vault_3"]}, "option": true}}
|
||||||
|
{"ref": "Has Room: Workshop (Tier 1)", "better": 0, "matchers": [{"string": "Workshop (Tier 1)"}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_temple_workshop_1"]}, "option": true}}
|
||||||
|
{"ref": "Has Shaper Influence", "better": 1, "matchers": [{"string": "Has Shaper Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_shaper_influence"]}}}
|
||||||
|
{"ref": "Has Warlord Influence", "better": 1, "matchers": [{"string": "Has Warlord Influence "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_has_warlord_influence"]}}}
|
||||||
|
{"ref": "Mirrored Tablet has # Islands", "better": 1, "matchers": [{"string": "Mirrored Tablet has # Islands "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_lake_number_of_islands"]}}}
|
||||||
|
{"ref": "More Currency: #%", "better": 1, "matchers": [{"string": "More Currency: #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_currency_drops"]}}}
|
||||||
|
{"ref": "More Divination Cards: #%", "better": 1, "matchers": [{"string": "More Divination Cards: #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_card_drops"]}}}
|
||||||
|
{"ref": "More Maps: #%", "better": 1, "matchers": [{"string": "More Maps: #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_map_drops"]}}}
|
||||||
|
{"ref": "More Scarabs: #%", "better": 1, "matchers": [{"string": "More Scarabs: #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_more_scarab_drops"]}}}
|
||||||
|
{"ref": "Quality (Attack Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Attack Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_attack_quality"]}}}
|
||||||
|
{"ref": "Quality (Attribute Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Attribute Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_attribute_quality"]}}}
|
||||||
|
{"ref": "Quality (Caster Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Caster Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_caster_quality"]}}}
|
||||||
|
{"ref": "Quality (Critical Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Critical Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_critical_quality"]}}}
|
||||||
|
{"ref": "Quality (Currency): #%", "better": 1, "matchers": [{"string": "Quality (Currency): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_currency"]}}}
|
||||||
|
{"ref": "Quality (Defence Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Defence Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_defense_quality"]}}}
|
||||||
|
{"ref": "Quality (Divination Cards): #%", "better": 1, "matchers": [{"string": "Quality (Divination Cards): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_cards"]}}}
|
||||||
|
{"ref": "Quality (Elemental Damage Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Elemental Damage Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_elemental_quality"]}}}
|
||||||
|
{"ref": "Quality (Life and Mana Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Life and Mana Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_resource_quality"]}}}
|
||||||
|
{"ref": "Quality (Pack Size): #%", "better": 1, "matchers": [{"string": "Quality (Pack Size): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_pack_size"]}}}
|
||||||
|
{"ref": "Quality (Physical and Chaos Damage Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Physical and Chaos Damage Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_physical_chaos_quality"]}}}
|
||||||
|
{"ref": "Quality (Rarity): #%", "better": 1, "matchers": [{"string": "Quality (Rarity): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_rarity"]}}}
|
||||||
|
{"ref": "Quality (Resistance Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Resistance Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_resistance_quality"]}}}
|
||||||
|
{"ref": "Quality (Scarabs): #%", "better": 1, "matchers": [{"string": "Quality (Scarabs): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_map_quality_scarabs"]}}}
|
||||||
|
{"ref": "Quality (Speed Modifiers): #%", "better": 1, "matchers": [{"string": "Quality (Speed Modifiers): #% "}], "trade": {"ids": {"pseudo": ["pseudo.pseudo_jewellery_speed_quality"]}}}
|
||||||
|
{"ref": "Reflection of Abyss (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Abyss (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_38892"]}}}
|
||||||
|
{"ref": "Reflection of Ambush (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Ambush (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_48307"]}}}
|
||||||
|
{"ref": "Reflection of Angling (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Angling (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_40794"]}}}
|
||||||
|
{"ref": "Reflection of Azurite (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Azurite (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_40031"]}}}
|
||||||
|
{"ref": "Reflection of Bestiary (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Bestiary (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_55569"]}}}
|
||||||
|
{"ref": "Reflection of Breach (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Breach (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_62572"]}}}
|
||||||
|
{"ref": "Reflection of Brutality (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Brutality (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_29096"]}}}
|
||||||
|
{"ref": "Reflection of Camaraderie (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Camaraderie (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_35395"]}}}
|
||||||
|
{"ref": "Reflection of Catalysis (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Catalysis (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_57850"]}}}
|
||||||
|
{"ref": "Reflection of Chaos (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Chaos (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_50834"]}}}
|
||||||
|
{"ref": "Reflection of Conflict (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Conflict (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_1931"]}}}
|
||||||
|
{"ref": "Reflection of Darkness (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Darkness (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_34457"]}}}
|
||||||
|
{"ref": "Reflection of Delirium (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Delirium (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_22138"]}}}
|
||||||
|
{"ref": "Reflection of Delve (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Delve (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_18737"]}}}
|
||||||
|
{"ref": "Reflection of Demonfire (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Demonfire (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_28500"]}}}
|
||||||
|
{"ref": "Reflection of Domination (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Domination (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_63412"]}}}
|
||||||
|
{"ref": "Reflection of Entrapment (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Entrapment (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_44399"]}}}
|
||||||
|
{"ref": "Reflection of Essence (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Essence (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_49862"]}}}
|
||||||
|
{"ref": "Reflection of Experimentation (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Experimentation (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_55676"]}}}
|
||||||
|
{"ref": "Reflection of Flame (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Flame (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_42468"]}}}
|
||||||
|
{"ref": "Reflection of Fractured Dimensions (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Fractured Dimensions (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_49488"]}}}
|
||||||
|
{"ref": "Reflection of Frost (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Frost (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_38110"]}}}
|
||||||
|
{"ref": "Reflection of Guilt (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Guilt (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_25480"]}}}
|
||||||
|
{"ref": "Reflection of Imprisonment (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Imprisonment (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_10363"]}}}
|
||||||
|
{"ref": "Reflection of Kalandra (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Kalandra (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_36591"]}}}
|
||||||
|
{"ref": "Reflection of Legion (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Legion (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_403"]}}}
|
||||||
|
{"ref": "Reflection of Metamorph (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Metamorph (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_3699"]}}}
|
||||||
|
{"ref": "Reflection of Occultism (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Occultism (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_24451"]}}}
|
||||||
|
{"ref": "Reflection of Paradise (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Paradise (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_50846"]}}}
|
||||||
|
{"ref": "Reflection of Perverted Faith (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Perverted Faith (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_27678"]}}}
|
||||||
|
{"ref": "Reflection of Phaaryl (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Phaaryl (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_7674"]}}}
|
||||||
|
{"ref": "Reflection of Possession (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Possession (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_25049"]}}}
|
||||||
|
{"ref": "Reflection of Power (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Power (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_35950"]}}}
|
||||||
|
{"ref": "Reflection of Scourge (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Scourge (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_62360"]}}}
|
||||||
|
{"ref": "Reflection of Stasis (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Stasis (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_32968"]}}}
|
||||||
|
{"ref": "Reflection of Sulphite (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Sulphite (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_45086"]}}}
|
||||||
|
{"ref": "Reflection of the Black Scythe (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Black Scythe (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_9662"]}}}
|
||||||
|
{"ref": "Reflection of the Breachlord (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Breachlord (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_62935"]}}}
|
||||||
|
{"ref": "Reflection of the Broken Circle (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Broken Circle (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_43128"]}}}
|
||||||
|
{"ref": "Reflection of the Chalice (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Chalice (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_64561"]}}}
|
||||||
|
{"ref": "Reflection of the Chasm (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Chasm (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_57101"]}}}
|
||||||
|
{"ref": "Reflection of the Dream (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Dream (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_27117"]}}}
|
||||||
|
{"ref": "Reflection of the Harbingers (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Harbingers (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_37203"]}}}
|
||||||
|
{"ref": "Reflection of the Hunter (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Hunter (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_18816"]}}}
|
||||||
|
{"ref": "Reflection of the Monolith (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Monolith (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_34796"]}}}
|
||||||
|
{"ref": "Reflection of the Nightmare (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Nightmare (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_24232"]}}}
|
||||||
|
{"ref": "Reflection of the Storm (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Storm (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_2745"]}}}
|
||||||
|
{"ref": "Reflection of the Sun (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Sun (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_60034"]}}}
|
||||||
|
{"ref": "Reflection of the Trove (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Trove (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_46772"]}}}
|
||||||
|
{"ref": "Reflection of the Wilderness (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of the Wilderness (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_29224"]}}}
|
||||||
|
{"ref": "Reflection of Thralldom (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Thralldom (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_26813"]}}}
|
||||||
|
{"ref": "Reflection of Torment (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Torment (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_53950"]}}}
|
||||||
|
{"ref": "Reflection of Tyranny (Difficulty #)", "better": 1, "matchers": [{"string": "Reflection of Tyranny (Difficulty #) "}], "trade": {"ids": {"pseudo": ["pseudo.lake_60981"]}}}
|
||||||