gotchi-battler-game-logic 3.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/cursor-rules.mdc +67 -0
- package/.cursor/rules/directory-structure.mdc +63 -0
- package/.cursor/rules/self-improvement.mdc +64 -0
- package/.cursor/rules/tech-stack.mdc +99 -0
- package/README.md +4 -0
- package/eslint.config.js +31 -0
- package/game-logic/index.js +2 -6
- package/game-logic/v1.4/constants.js +0 -23
- package/game-logic/v1.4/index.js +64 -56
- package/game-logic/v1.5/constants.js +0 -23
- package/game-logic/v1.5/index.js +27 -21
- package/game-logic/v1.6/constants.js +0 -23
- package/game-logic/v1.6/index.js +27 -21
- package/game-logic/v1.7/constants.js +0 -23
- package/game-logic/v1.7/helpers.js +2 -2
- package/game-logic/v1.7/index.js +24 -18
- package/game-logic/v1.8/constants.js +0 -23
- package/game-logic/v1.8/helpers.js +2 -2
- package/game-logic/v1.8/index.js +25 -19
- package/game-logic/v2.0/constants.js +112 -0
- package/game-logic/v2.0/helpers.js +713 -0
- package/game-logic/v2.0/index.js +782 -0
- package/game-logic/v2.0/statuses.json +439 -0
- package/package.json +11 -4
- package/schemas/crystal.js +14 -0
- package/schemas/effect.js +25 -0
- package/schemas/gotchi.js +53 -0
- package/schemas/ingameteam.js +14 -0
- package/schemas/item.js +13 -0
- package/schemas/leaderskill.js +15 -0
- package/schemas/leaderskillstatus.js +12 -0
- package/schemas/special.js +22 -0
- package/schemas/team.js +24 -0
- package/schemas/team.json +252 -114
- package/scripts/balancing/createTrainingGotchis.js +44 -44
- package/scripts/balancing/extractOnchainTraits.js +3 -3
- package/scripts/balancing/fixTrainingGotchis.js +41 -41
- package/scripts/balancing/processSims.js +5 -5
- package/scripts/balancing/sims.js +8 -15
- package/scripts/balancing/v1.7/setTeamPositions.js +2 -2
- package/scripts/balancing/v1.7.1/setTeamPositions.js +2 -2
- package/scripts/balancing/v1.7.2/setTeamPositions.js +2 -2
- package/scripts/balancing/v1.7.3/setTeamPositions.js +2 -2
- package/scripts/data/dungeon_mob_1.json +87 -0
- package/scripts/data/dungeon_mob_2.json +87 -0
- package/scripts/data/immaterialTeam1.json +374 -0
- package/scripts/data/immaterialTeam2.json +365 -0
- package/scripts/generateAllSpecialsLogs.js +93 -0
- package/scripts/generateSpecialLogs.js +94 -0
- package/scripts/runCampaignBattles.js +41 -0
- package/scripts/runLocalBattle.js +6 -3
- package/scripts/runLocalDungeon.js +52 -0
- package/scripts/runPvPBattle.js +15 -0
- package/scripts/runRealBattle.js +8 -8
- package/scripts/simRealBattle.js +8 -8
- package/scripts/validateBattle.js +12 -14
- package/scripts/validateTournament.js +9 -9
- package/tests/getModifiedStats.test.js +78 -0
- package/utils/errors.js +13 -13
- package/utils/transforms.js +2 -8
- package/scripts/output/.gitkeep +0 -0
|
@@ -4,60 +4,60 @@ const { mapGotchi } = require('../../utils/mapGotchi')
|
|
|
4
4
|
|
|
5
5
|
const specials = [
|
|
6
6
|
{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
'id': 1,
|
|
8
|
+
'class': 'Ninja',
|
|
9
|
+
'name': 'Spectral strike',
|
|
10
|
+
'cooldown': 0,
|
|
11
|
+
'leaderPassive': 'Sharpen blades'
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
'id': 2,
|
|
15
|
+
'class': 'Enlightened',
|
|
16
|
+
'name': 'Meditate',
|
|
17
|
+
'cooldown': 0,
|
|
18
|
+
'leaderPassive': 'Cloud of Zen'
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
'id': 3,
|
|
22
|
+
'class': 'Cleaver',
|
|
23
|
+
'name': 'Cleave',
|
|
24
|
+
'cooldown': 2,
|
|
25
|
+
'leaderPassive': 'Frenzy'
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
'id': 4,
|
|
29
|
+
'class': 'Tank',
|
|
30
|
+
'name': 'Taunt',
|
|
31
|
+
'cooldown': 0,
|
|
32
|
+
'leaderPassive': 'Fortify'
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
'id': 5,
|
|
36
|
+
'class': 'Cursed',
|
|
37
|
+
'name': 'Curse',
|
|
38
|
+
'cooldown': 0,
|
|
39
|
+
'leaderPassive': 'Spread the fear'
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
'id': 6,
|
|
43
|
+
'class': 'Healer',
|
|
44
|
+
'name': 'Blessing',
|
|
45
|
+
'cooldown': 0,
|
|
46
|
+
'leaderPassive': 'Cleansing Aura'
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
'id': 7,
|
|
50
|
+
'class': 'Mage',
|
|
51
|
+
'name': 'Thunder',
|
|
52
|
+
'cooldown': 2,
|
|
53
|
+
'leaderPassive': 'Channel the coven'
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
'id': 8,
|
|
57
|
+
'class': 'Troll',
|
|
58
|
+
'name': 'Devestating Smash',
|
|
59
|
+
'cooldown': 2,
|
|
60
|
+
'leaderPassive': 'Clan momentum'
|
|
61
61
|
}
|
|
62
62
|
]
|
|
63
63
|
|
|
@@ -65,7 +65,7 @@ const classes = ['Ninja','Enlightened','Cleaver','Tank','Cursed','Healer', 'Mage
|
|
|
65
65
|
const powerLevels = ['Godlike', 'Mythical', 'Legendary', 'Rare', 'Uncommon', 'Common', 'Garbage']
|
|
66
66
|
|
|
67
67
|
const addAvgGotchs = () => {
|
|
68
|
-
const statsToOverwrite = [
|
|
68
|
+
const statsToOverwrite = ['speed', 'health', 'crit', 'armor', 'evade', 'resist', 'accuracy']
|
|
69
69
|
|
|
70
70
|
const avgGotchis = [];
|
|
71
71
|
|
|
@@ -41,16 +41,16 @@ const classes = ['Ninja','Enlightened','Cleaver','Tank','Cursed','Healer', 'Mage
|
|
|
41
41
|
|
|
42
42
|
const calculateKpis = (data) => {
|
|
43
43
|
// Extract wins values
|
|
44
|
-
const wins = data.map(item => item.wins)
|
|
44
|
+
const wins = data.map(item => item.wins)
|
|
45
45
|
|
|
46
46
|
// Calculate the mean of wins
|
|
47
|
-
const winsMean = wins.reduce((sum, value) => sum + value, 0) / wins.length
|
|
47
|
+
const winsMean = wins.reduce((sum, value) => sum + value, 0) / wins.length
|
|
48
48
|
|
|
49
49
|
// Calculate the wins per slot
|
|
50
50
|
const winsPerSlot = winsMean / 5
|
|
51
51
|
|
|
52
52
|
// Calculate the standard deviation of wins
|
|
53
|
-
const winsVariance = wins.reduce((sum, value) => sum + Math.pow(value - winsMean, 2), 0) / (wins.length - 1)
|
|
53
|
+
const winsVariance = wins.reduce((sum, value) => sum + Math.pow(value - winsMean, 2), 0) / (wins.length - 1)
|
|
54
54
|
const winsStdev = Math.sqrt(winsVariance)
|
|
55
55
|
|
|
56
56
|
// Calculate Interquartile Range (IQR)
|
|
@@ -91,8 +91,8 @@ const calculateKpis = (data) => {
|
|
|
91
91
|
// G is power level, avg is trait combo, 1 is class number, B is formation position
|
|
92
92
|
const leaderWins = data.filter(item => item.slot1.includes(`${i + 1}`)).map(item => item.wins)
|
|
93
93
|
|
|
94
|
-
const leaderWinsMean = leaderWins.reduce((sum, value) => sum + value, 0) / leaderWins.length
|
|
95
|
-
const leaderWinsVariance = leaderWins.reduce((sum, value) => sum + Math.pow(value - leaderWinsMean, 2), 0) / (leaderWins.length - 1)
|
|
94
|
+
const leaderWinsMean = leaderWins.reduce((sum, value) => sum + value, 0) / leaderWins.length
|
|
95
|
+
const leaderWinsVariance = leaderWins.reduce((sum, value) => sum + Math.pow(value - leaderWinsMean, 2), 0) / (leaderWins.length - 1)
|
|
96
96
|
const leaderWinsStdev = Math.sqrt(leaderWinsVariance)
|
|
97
97
|
|
|
98
98
|
// Calculate Interquartile Range (IQR)
|
|
@@ -125,7 +125,7 @@ const getGotchisSimNameFromTeam = (team) => {
|
|
|
125
125
|
|
|
126
126
|
[0,1,2,3,4].forEach(i => {
|
|
127
127
|
const gotchi = team.formation.back[i] || team.formation.front[i]
|
|
128
|
-
const position =
|
|
128
|
+
const position = team.formation.back[i] ? 'B' : 'F'
|
|
129
129
|
|
|
130
130
|
const nameParts = gotchi.name.split(' ')
|
|
131
131
|
// Return e.g. "R|++++|1_B"
|
|
@@ -139,7 +139,7 @@ const runSims = async (simsVersion, gameLogicVersion, simsPerMatchup) => {
|
|
|
139
139
|
const classCombos = require(`./${simsVersion}/class_combos.js`)
|
|
140
140
|
const classTraitCombos = require(`./${simsVersion}/trait_combos.json`)
|
|
141
141
|
const setTeamPositions = require(`./${simsVersion}/setTeamPositions`)
|
|
142
|
-
const gameLogic = require(
|
|
142
|
+
const gameLogic = require('../../game-logic')[gameLogicVersion].gameLoop
|
|
143
143
|
|
|
144
144
|
const attackingPowerLevels = ['Godlike']
|
|
145
145
|
const defendingPowerLevels = ['Godlike', 'Mythical', 'Legendary']
|
|
@@ -181,7 +181,7 @@ const runSims = async (simsVersion, gameLogicVersion, simsPerMatchup) => {
|
|
|
181
181
|
|
|
182
182
|
console.time(`Sims for ${attackingTeam.name}`)
|
|
183
183
|
|
|
184
|
-
defendingTeamIndexes.forEach((defendingTeamIndex
|
|
184
|
+
defendingTeamIndexes.forEach((defendingTeamIndex) => {
|
|
185
185
|
const defendingTeam = createTeamFromTeamIndex(defendingTeamIndex, trainingGotchis, setTeamPositions)
|
|
186
186
|
|
|
187
187
|
let matchupWins = 0
|
|
@@ -231,23 +231,16 @@ const runSims = async (simsVersion, gameLogicVersion, simsPerMatchup) => {
|
|
|
231
231
|
|
|
232
232
|
if (process.env.CLOUD_RUN_JOB && process.env.SIMS_BUCKET) {
|
|
233
233
|
// Save as JSON to GCS
|
|
234
|
-
|
|
235
|
-
await storage.bucket(process.env.SIMS_BUCKET).file(`${process.env.CLOUD_RUN_EXECUTION}_${attackingTeamIndex}.json`).save(JSON.stringify(results))
|
|
236
|
-
} catch (err) {
|
|
237
|
-
throw err
|
|
238
|
-
}
|
|
234
|
+
await storage.bucket(process.env.SIMS_BUCKET).file(`${process.env.CLOUD_RUN_EXECUTION}_${attackingTeamIndex}.json`).save(JSON.stringify(results))
|
|
239
235
|
|
|
240
236
|
} else {
|
|
241
|
-
|
|
237
|
+
console.log('Results', results)
|
|
242
238
|
|
|
243
239
|
// Test saving to GCS
|
|
244
|
-
|
|
240
|
+
const test = false
|
|
241
|
+
if (test) {
|
|
245
242
|
process.env.GOOGLE_APPLICATION_CREDENTIALS = path.join(__dirname, '../../keyfile.json')
|
|
246
|
-
|
|
247
|
-
await storage.bucket(process.env.SIMS_BUCKET).file(`avg-sims-znw68_${attackingTeamIndex}.json`).save(JSON.stringify(results))
|
|
248
|
-
} catch (err) {
|
|
249
|
-
throw err
|
|
250
|
-
}
|
|
243
|
+
await storage.bucket(process.env.SIMS_BUCKET).file(`avg-sims-znw68_${attackingTeamIndex}.json`).save(JSON.stringify(results))
|
|
251
244
|
}
|
|
252
245
|
}
|
|
253
246
|
}
|
|
@@ -70,7 +70,7 @@ module.exports = (team) => {
|
|
|
70
70
|
const frontGotchis = team.formation.front.filter(gotchi => gotchi)
|
|
71
71
|
if (frontGotchis.length === 5) {
|
|
72
72
|
// Sort the gotchis by score in ascending order (lowest score first)
|
|
73
|
-
const orderedGotchis = JSON.parse(JSON.stringify(frontGotchis)).sort((a, b) => getFrontRowScore(a.id, team.leader) - getFrontRowScore(b.id, team.leader))
|
|
73
|
+
const orderedGotchis = JSON.parse(JSON.stringify(frontGotchis)).sort((a, b) => getFrontRowScore(a.id, team.leader) - getFrontRowScore(b.id, team.leader))
|
|
74
74
|
|
|
75
75
|
// Loop through the front row and the first 2 gotchis that have a score of either orderedGotchis[0] or orderedGotchis[1] move to the back
|
|
76
76
|
let hasMoved = 0
|
|
@@ -88,7 +88,7 @@ module.exports = (team) => {
|
|
|
88
88
|
const backGotchis = team.formation.back.filter(gotchi => gotchi)
|
|
89
89
|
if (backGotchis.length === 5) {
|
|
90
90
|
// Sort the gotchis by score in descending order (highest score first)
|
|
91
|
-
const orderedGotchis = JSON.parse(JSON.stringify(backGotchis)).sort((a, b) => getFrontRowScore(b.id, team.leader) - getFrontRowScore(a.id, team.leader))
|
|
91
|
+
const orderedGotchis = JSON.parse(JSON.stringify(backGotchis)).sort((a, b) => getFrontRowScore(b.id, team.leader) - getFrontRowScore(a.id, team.leader))
|
|
92
92
|
|
|
93
93
|
// Loop through the back row and the first 2 gotchis that have a score of either orderedGotchis[0] or orderedGotchis[1] move to the front
|
|
94
94
|
let hasMoved = 0
|
|
@@ -87,7 +87,7 @@ module.exports = (team) => {
|
|
|
87
87
|
const frontGotchis = team.formation.front.filter(gotchi => gotchi)
|
|
88
88
|
if (frontGotchis.length === 5) {
|
|
89
89
|
// Sort the gotchis by score in ascending order (lowest score first)
|
|
90
|
-
const orderedGotchis = JSON.parse(JSON.stringify(frontGotchis)).sort((a, b) => getFrontRowScore(a.id, team.leader) - getFrontRowScore(b.id, team.leader))
|
|
90
|
+
const orderedGotchis = JSON.parse(JSON.stringify(frontGotchis)).sort((a, b) => getFrontRowScore(a.id, team.leader) - getFrontRowScore(b.id, team.leader))
|
|
91
91
|
|
|
92
92
|
// Loop through the front row and the first 2 gotchis that have a score of either orderedGotchis[0] or orderedGotchis[1] move to the back
|
|
93
93
|
let hasMoved = 0
|
|
@@ -105,7 +105,7 @@ module.exports = (team) => {
|
|
|
105
105
|
const backGotchis = team.formation.back.filter(gotchi => gotchi)
|
|
106
106
|
if (backGotchis.length === 5) {
|
|
107
107
|
// Sort the gotchis by score in descending order (highest score first)
|
|
108
|
-
const orderedGotchis = JSON.parse(JSON.stringify(backGotchis)).sort((a, b) => getFrontRowScore(b.id, team.leader) - getFrontRowScore(a.id, team.leader))
|
|
108
|
+
const orderedGotchis = JSON.parse(JSON.stringify(backGotchis)).sort((a, b) => getFrontRowScore(b.id, team.leader) - getFrontRowScore(a.id, team.leader))
|
|
109
109
|
|
|
110
110
|
// Loop through the back row and the first 2 gotchis that have a score of either orderedGotchis[0] or orderedGotchis[1] move to the front
|
|
111
111
|
let hasMoved = 0
|
|
@@ -87,7 +87,7 @@ module.exports = (team) => {
|
|
|
87
87
|
const frontGotchis = team.formation.front.filter(gotchi => gotchi)
|
|
88
88
|
if (frontGotchis.length === 5) {
|
|
89
89
|
// Sort the gotchis by score in ascending order (lowest score first)
|
|
90
|
-
const orderedGotchis = JSON.parse(JSON.stringify(frontGotchis)).sort((a, b) => getFrontRowScore(a.id, team.leader) - getFrontRowScore(b.id, team.leader))
|
|
90
|
+
const orderedGotchis = JSON.parse(JSON.stringify(frontGotchis)).sort((a, b) => getFrontRowScore(a.id, team.leader) - getFrontRowScore(b.id, team.leader))
|
|
91
91
|
|
|
92
92
|
// Loop through the front row and the first 2 gotchis that have a score of either orderedGotchis[0] or orderedGotchis[1] move to the back
|
|
93
93
|
let hasMoved = 0
|
|
@@ -105,7 +105,7 @@ module.exports = (team) => {
|
|
|
105
105
|
const backGotchis = team.formation.back.filter(gotchi => gotchi)
|
|
106
106
|
if (backGotchis.length === 5) {
|
|
107
107
|
// Sort the gotchis by score in descending order (highest score first)
|
|
108
|
-
const orderedGotchis = JSON.parse(JSON.stringify(backGotchis)).sort((a, b) => getFrontRowScore(b.id, team.leader) - getFrontRowScore(a.id, team.leader))
|
|
108
|
+
const orderedGotchis = JSON.parse(JSON.stringify(backGotchis)).sort((a, b) => getFrontRowScore(b.id, team.leader) - getFrontRowScore(a.id, team.leader))
|
|
109
109
|
|
|
110
110
|
// Loop through the back row and the first 2 gotchis that have a score of either orderedGotchis[0] or orderedGotchis[1] move to the front
|
|
111
111
|
let hasMoved = 0
|
|
@@ -87,7 +87,7 @@ module.exports = (team) => {
|
|
|
87
87
|
const frontGotchis = team.formation.front.filter(gotchi => gotchi)
|
|
88
88
|
if (frontGotchis.length === 5) {
|
|
89
89
|
// Sort the gotchis by score in ascending order (lowest score first)
|
|
90
|
-
const orderedGotchis = JSON.parse(JSON.stringify(frontGotchis)).sort((a, b) => getFrontRowScore(a.id, team.leader) - getFrontRowScore(b.id, team.leader))
|
|
90
|
+
const orderedGotchis = JSON.parse(JSON.stringify(frontGotchis)).sort((a, b) => getFrontRowScore(a.id, team.leader) - getFrontRowScore(b.id, team.leader))
|
|
91
91
|
|
|
92
92
|
// Loop through the front row and the first 2 gotchis that have a score of either orderedGotchis[0] or orderedGotchis[1] move to the back
|
|
93
93
|
let hasMoved = 0
|
|
@@ -105,7 +105,7 @@ module.exports = (team) => {
|
|
|
105
105
|
const backGotchis = team.formation.back.filter(gotchi => gotchi)
|
|
106
106
|
if (backGotchis.length === 5) {
|
|
107
107
|
// Sort the gotchis by score in descending order (highest score first)
|
|
108
|
-
const orderedGotchis = JSON.parse(JSON.stringify(backGotchis)).sort((a, b) => getFrontRowScore(b.id, team.leader) - getFrontRowScore(a.id, team.leader))
|
|
108
|
+
const orderedGotchis = JSON.parse(JSON.stringify(backGotchis)).sort((a, b) => getFrontRowScore(b.id, team.leader) - getFrontRowScore(a.id, team.leader))
|
|
109
109
|
|
|
110
110
|
// Loop through the back row and the first 2 gotchis that have a score of either orderedGotchis[0] or orderedGotchis[1] move to the front
|
|
111
111
|
let hasMoved = 0
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"formation": {
|
|
3
|
+
"front": [
|
|
4
|
+
null,
|
|
5
|
+
{
|
|
6
|
+
"id": 539,
|
|
7
|
+
"name": "Spider",
|
|
8
|
+
"enemyId": "SPIDER",
|
|
9
|
+
"speed": 200,
|
|
10
|
+
"health": 400,
|
|
11
|
+
"crit": 0,
|
|
12
|
+
"armor": 50,
|
|
13
|
+
"evade": 5,
|
|
14
|
+
"resist": 0,
|
|
15
|
+
"magic": 300,
|
|
16
|
+
"physical": 150,
|
|
17
|
+
"accuracy": 90,
|
|
18
|
+
"attack": "magic",
|
|
19
|
+
"specialId": 7,
|
|
20
|
+
"special": {
|
|
21
|
+
"id": 7,
|
|
22
|
+
"class": "Mage",
|
|
23
|
+
"name": "Thunder",
|
|
24
|
+
"cooldown": 2,
|
|
25
|
+
"leaderPassive": "Channel the coven"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
null,
|
|
29
|
+
{
|
|
30
|
+
"id": 540,
|
|
31
|
+
"name": "Spider",
|
|
32
|
+
"enemyId": "SPIDER",
|
|
33
|
+
"speed": 200,
|
|
34
|
+
"health": 400,
|
|
35
|
+
"crit": 0,
|
|
36
|
+
"armor": 50,
|
|
37
|
+
"evade": 5,
|
|
38
|
+
"resist": 0,
|
|
39
|
+
"magic": 300,
|
|
40
|
+
"physical": 150,
|
|
41
|
+
"accuracy": 90,
|
|
42
|
+
"attack": "magic",
|
|
43
|
+
"specialId": 7,
|
|
44
|
+
"special": {
|
|
45
|
+
"id": 7,
|
|
46
|
+
"class": "Mage",
|
|
47
|
+
"name": "Thunder",
|
|
48
|
+
"cooldown": 2,
|
|
49
|
+
"leaderPassive": "Channel the coven"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
null
|
|
53
|
+
],
|
|
54
|
+
"back": [
|
|
55
|
+
null,
|
|
56
|
+
null,
|
|
57
|
+
{
|
|
58
|
+
"id": 541,
|
|
59
|
+
"name": "Spider",
|
|
60
|
+
"enemyId": "SPIDER",
|
|
61
|
+
"speed": 200,
|
|
62
|
+
"health": 400,
|
|
63
|
+
"crit": 0,
|
|
64
|
+
"armor": 50,
|
|
65
|
+
"evade": 5,
|
|
66
|
+
"resist": 0,
|
|
67
|
+
"magic": 300,
|
|
68
|
+
"physical": 150,
|
|
69
|
+
"accuracy": 90,
|
|
70
|
+
"attack": "magic",
|
|
71
|
+
"specialId": 7,
|
|
72
|
+
"special": {
|
|
73
|
+
"id": 7,
|
|
74
|
+
"class": "Mage",
|
|
75
|
+
"name": "Thunder",
|
|
76
|
+
"cooldown": 2,
|
|
77
|
+
"leaderPassive": "Channel the coven"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
null,
|
|
81
|
+
null
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"leader": 540,
|
|
85
|
+
"name": "Dungeon Mob 1",
|
|
86
|
+
"owner": "0x10B989914A478Ed7DE2d2C4CC4e835bbd3de229b"
|
|
87
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"formation": {
|
|
3
|
+
"front": [
|
|
4
|
+
null,
|
|
5
|
+
{
|
|
6
|
+
"id": 1539,
|
|
7
|
+
"name": "Bat",
|
|
8
|
+
"enemyId": "BAT",
|
|
9
|
+
"speed": 200,
|
|
10
|
+
"health": 400,
|
|
11
|
+
"crit": 0,
|
|
12
|
+
"armor": 50,
|
|
13
|
+
"evade": 5,
|
|
14
|
+
"resist": 0,
|
|
15
|
+
"magic": 300,
|
|
16
|
+
"physical": 150,
|
|
17
|
+
"accuracy": 90,
|
|
18
|
+
"attack": "magic",
|
|
19
|
+
"specialId": 7,
|
|
20
|
+
"special": {
|
|
21
|
+
"id": 7,
|
|
22
|
+
"class": "Mage",
|
|
23
|
+
"name": "Thunder",
|
|
24
|
+
"cooldown": 2,
|
|
25
|
+
"leaderPassive": "Channel the coven"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
null,
|
|
29
|
+
{
|
|
30
|
+
"id": 1540,
|
|
31
|
+
"name": "Bat",
|
|
32
|
+
"enemyId": "BAT",
|
|
33
|
+
"speed": 200,
|
|
34
|
+
"health": 400,
|
|
35
|
+
"crit": 0,
|
|
36
|
+
"armor": 50,
|
|
37
|
+
"evade": 5,
|
|
38
|
+
"resist": 0,
|
|
39
|
+
"magic": 300,
|
|
40
|
+
"physical": 150,
|
|
41
|
+
"accuracy": 90,
|
|
42
|
+
"attack": "magic",
|
|
43
|
+
"specialId": 7,
|
|
44
|
+
"special": {
|
|
45
|
+
"id": 7,
|
|
46
|
+
"class": "Mage",
|
|
47
|
+
"name": "Thunder",
|
|
48
|
+
"cooldown": 2,
|
|
49
|
+
"leaderPassive": "Channel the coven"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
null
|
|
53
|
+
],
|
|
54
|
+
"back": [
|
|
55
|
+
null,
|
|
56
|
+
null,
|
|
57
|
+
{
|
|
58
|
+
"id": 1541,
|
|
59
|
+
"name": "Bat",
|
|
60
|
+
"enemyId": "BAT",
|
|
61
|
+
"speed": 200,
|
|
62
|
+
"health": 400,
|
|
63
|
+
"crit": 0,
|
|
64
|
+
"armor": 50,
|
|
65
|
+
"evade": 5,
|
|
66
|
+
"resist": 0,
|
|
67
|
+
"magic": 300,
|
|
68
|
+
"physical": 150,
|
|
69
|
+
"accuracy": 90,
|
|
70
|
+
"attack": "magic",
|
|
71
|
+
"specialId": 7,
|
|
72
|
+
"special": {
|
|
73
|
+
"id": 7,
|
|
74
|
+
"class": "Mage",
|
|
75
|
+
"name": "Thunder",
|
|
76
|
+
"cooldown": 2,
|
|
77
|
+
"leaderPassive": "Channel the coven"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
null,
|
|
81
|
+
null
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"leader": 1540,
|
|
85
|
+
"name": "Dungeon Mob 2",
|
|
86
|
+
"owner": "0x10B989914A478Ed7DE2d2C4CC4e835bbd3de229b"
|
|
87
|
+
}
|