mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-27 10:42:25 +02:00
Complete basic implementation of Tera
This commit is contained in:
parent
e2d0939050
commit
5097b21851
709
public/battle-anims/terastallize.json
Normal file
709
public/battle-anims/terastallize.json
Normal file
@ -0,0 +1,709 @@
|
|||||||
|
{
|
||||||
|
"graphic": "terastallize",
|
||||||
|
"frames": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 225,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 70,
|
||||||
|
"zoomY": 70,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 70,
|
||||||
|
"zoomY": 70,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 90,
|
||||||
|
"zoomY": 90,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 90,
|
||||||
|
"zoomY": 90,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 200,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"tone": [100,100,100,0],
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"tone": [100,100,100,0],
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"tone": [100,100,100,0],
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 60,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"tone": [100,100,100,0],
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 60,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"tone": [100,100,100,0],
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 60,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"tone": [100,100,100,0],
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"tone": [255,255,255,255],
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"tone": [255,255,255,0],
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"tone": [255,255,255,255],
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 1}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"position": 4,
|
||||||
|
"hue": 0
|
||||||
|
}
|
BIN
public/images/battle_anims/terastallize.png
Normal file
BIN
public/images/battle_anims/terastallize.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
@ -1 +1 @@
|
|||||||
Subproject commit 5ef993b95fa8248adc0fb7d9489baccf546bf8e3
|
Subproject commit a7a986de64c383671854d9cc5de97d03daac02fa
|
@ -9,7 +9,7 @@ import type { Constructor } from "#app/utils";
|
|||||||
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import type { Modifier, ModifierPredicate, TurnHeldItemTransferModifier } from "./modifier/modifier";
|
import type { Modifier, ModifierPredicate, TurnHeldItemTransferModifier } from "./modifier/modifier";
|
||||||
import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, ModifierBar, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, RememberMoveModifier, TerastallizeModifier } from "./modifier/modifier";
|
import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, ModifierBar, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, RememberMoveModifier } from "./modifier/modifier";
|
||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "#app/data/battle-anims";
|
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "#app/data/battle-anims";
|
||||||
import type { Phase } from "#app/phase";
|
import type { Phase } from "#app/phase";
|
||||||
@ -1655,7 +1655,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initPokemonSprite(sprite: Phaser.GameObjects.Sprite, pokemon?: Pokemon, hasShadow: boolean = false, ignoreOverride: boolean = false): Phaser.GameObjects.Sprite {
|
initPokemonSprite(sprite: Phaser.GameObjects.Sprite, pokemon?: Pokemon, hasShadow: boolean = false, ignoreOverride: boolean = false): Phaser.GameObjects.Sprite {
|
||||||
sprite.setPipeline(this.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: hasShadow, ignoreOverride: ignoreOverride, teraColor: pokemon ? getTypeRgb(pokemon.getTeraType()) : undefined });
|
sprite.setPipeline(this.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: hasShadow, ignoreOverride: ignoreOverride, teraColor: pokemon ? getTypeRgb(pokemon.getTeraType()) : undefined, isTerastallized: pokemon ? pokemon.isTerastallized : false });
|
||||||
this.spriteSparkleHandler.add(sprite);
|
this.spriteSparkleHandler.add(sprite);
|
||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
@ -2574,11 +2574,8 @@ export default class BattleScene extends SceneBase {
|
|||||||
const modifiersToRemove: PersistentModifier[] = [];
|
const modifiersToRemove: PersistentModifier[] = [];
|
||||||
const modifierPromises: Promise<boolean>[] = [];
|
const modifierPromises: Promise<boolean>[] = [];
|
||||||
if (modifier instanceof PersistentModifier) {
|
if (modifier instanceof PersistentModifier) {
|
||||||
if (modifier instanceof TerastallizeModifier) {
|
|
||||||
modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId)));
|
|
||||||
}
|
|
||||||
if ((modifier as PersistentModifier).add(this.modifiers, !!virtual)) {
|
if ((modifier as PersistentModifier).add(this.modifiers, !!virtual)) {
|
||||||
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
if (modifier instanceof PokemonFormChangeItemModifier) {
|
||||||
const pokemon = this.getPokemonById(modifier.pokemonId);
|
const pokemon = this.getPokemonById(modifier.pokemonId);
|
||||||
if (pokemon) {
|
if (pokemon) {
|
||||||
success = modifier.apply(pokemon, true);
|
success = modifier.apply(pokemon, true);
|
||||||
@ -2655,11 +2652,8 @@ export default class BattleScene extends SceneBase {
|
|||||||
addEnemyModifier(modifier: PersistentModifier, ignoreUpdate?: boolean, instant?: boolean): Promise<void> {
|
addEnemyModifier(modifier: PersistentModifier, ignoreUpdate?: boolean, instant?: boolean): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const modifiersToRemove: PersistentModifier[] = [];
|
const modifiersToRemove: PersistentModifier[] = [];
|
||||||
if (modifier instanceof TerastallizeModifier) {
|
|
||||||
modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId, false)));
|
|
||||||
}
|
|
||||||
if ((modifier as PersistentModifier).add(this.enemyModifiers, false)) {
|
if ((modifier as PersistentModifier).add(this.enemyModifiers, false)) {
|
||||||
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
if (modifier instanceof PokemonFormChangeItemModifier) {
|
||||||
const pokemon = this.getPokemonById(modifier.pokemonId);
|
const pokemon = this.getPokemonById(modifier.pokemonId);
|
||||||
if (pokemon) {
|
if (pokemon) {
|
||||||
modifier.apply(pokemon, true);
|
modifier.apply(pokemon, true);
|
||||||
@ -2783,6 +2777,8 @@ export default class BattleScene extends SceneBase {
|
|||||||
for (const modifier of modifiers) {
|
for (const modifier of modifiers) {
|
||||||
this.addEnemyModifier(modifier, true, true);
|
this.addEnemyModifier(modifier, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.currentBattle.trainer.genAI(party);
|
||||||
}
|
}
|
||||||
|
|
||||||
party.forEach((enemyPokemon: EnemyPokemon, i: integer) => {
|
party.forEach((enemyPokemon: EnemyPokemon, i: integer) => {
|
||||||
@ -2914,7 +2910,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
const modifierIndex = modifiers.indexOf(modifier);
|
const modifierIndex = modifiers.indexOf(modifier);
|
||||||
if (modifierIndex > -1) {
|
if (modifierIndex > -1) {
|
||||||
modifiers.splice(modifierIndex, 1);
|
modifiers.splice(modifierIndex, 1);
|
||||||
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
if (modifier instanceof PokemonFormChangeItemModifier) {
|
||||||
const pokemon = this.getPokemonById(modifier.pokemonId);
|
const pokemon = this.getPokemonById(modifier.pokemonId);
|
||||||
if (pokemon) {
|
if (pokemon) {
|
||||||
modifier.apply(pokemon, false);
|
modifier.apply(pokemon, false);
|
||||||
@ -3115,7 +3111,8 @@ export default class BattleScene extends SceneBase {
|
|||||||
name: p.name,
|
name: p.name,
|
||||||
form: p.getFormKey(),
|
form: p.getFormKey(),
|
||||||
types: p.getTypes().map((type) => Type[type]),
|
types: p.getTypes().map((type) => Type[type]),
|
||||||
teraType: p.getTeraType() !== Type.UNKNOWN ? Type[p.getTeraType()] : "",
|
teraType: Type[p.getTeraType()],
|
||||||
|
isTerastallized: p.isTerastallized,
|
||||||
level: p.level,
|
level: p.level,
|
||||||
currentHP: p.hp,
|
currentHP: p.hp,
|
||||||
maxHP: p.getMaxHp(),
|
maxHP: p.getMaxHp(),
|
||||||
|
@ -68,7 +68,6 @@ export interface TurnCommand {
|
|||||||
targets?: BattlerIndex[];
|
targets?: BattlerIndex[];
|
||||||
skip?: boolean;
|
skip?: boolean;
|
||||||
args?: any[];
|
args?: any[];
|
||||||
preturnCommands?: Command[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FaintLogEntry {
|
export interface FaintLogEntry {
|
||||||
@ -93,6 +92,7 @@ export default class Battle {
|
|||||||
public started: boolean = false;
|
public started: boolean = false;
|
||||||
public enemySwitchCounter: number = 0;
|
public enemySwitchCounter: number = 0;
|
||||||
public turn: number = 0;
|
public turn: number = 0;
|
||||||
|
public preTurnCommands: TurnCommands;
|
||||||
public turnCommands: TurnCommands;
|
public turnCommands: TurnCommands;
|
||||||
public playerParticipantIds: Set<number> = new Set<number>();
|
public playerParticipantIds: Set<number> = new Set<number>();
|
||||||
public battleScore: number = 0;
|
public battleScore: number = 0;
|
||||||
@ -176,6 +176,7 @@ export default class Battle {
|
|||||||
incrementTurn(): void {
|
incrementTurn(): void {
|
||||||
this.turn++;
|
this.turn++;
|
||||||
this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ]));
|
this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ]));
|
||||||
|
this.preTurnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ]));
|
||||||
this.battleSeedState = null;
|
this.battleSeedState = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,37 +239,25 @@ export class PostBattleInitFormChangeAbAttr extends PostBattleInitAbAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PostBattleInitStatStageChangeAbAttr extends PostBattleInitAbAttr {
|
export class PostTeraFormChangeStatChangeAbAttr extends AbAttr {
|
||||||
private stats: BattleStat[];
|
private stats: BattleStat[];
|
||||||
private stages: number;
|
private stages: number;
|
||||||
private selfTarget: boolean;
|
|
||||||
|
|
||||||
constructor(stats: BattleStat[], stages: number, selfTarget?: boolean) {
|
constructor(stats: BattleStat[], stages: number) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.stats = stats;
|
this.stats = stats;
|
||||||
this.stages = stages;
|
this.stages = stages;
|
||||||
this.selfTarget = !!selfTarget;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostBattleInit(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder | null, args: any[]): boolean | Promise<boolean> {
|
||||||
const statStageChangePhases: StatStageChangePhase[] = [];
|
const statStageChangePhases: StatStageChangePhase[] = [];
|
||||||
|
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
if (this.selfTarget) {
|
statStageChangePhases.push(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
|
||||||
statStageChangePhases.push(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
|
|
||||||
} else {
|
|
||||||
for (const opponent of pokemon.getOpponents()) {
|
|
||||||
statStageChangePhases.push(new StatStageChangePhase(opponent.getBattlerIndex(), false, this.stats, this.stages));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const statStageChangePhase of statStageChangePhases) {
|
for (const statStageChangePhase of statStageChangePhases) {
|
||||||
if (!this.selfTarget && !statStageChangePhase.getPokemon()?.summonData) {
|
globalScene.unshiftPhase(statStageChangePhase);
|
||||||
globalScene.pushPhase(statStageChangePhase);
|
|
||||||
} else { // TODO: This causes the ability bar to be shown at the wrong time
|
|
||||||
globalScene.unshiftPhase(statStageChangePhase);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6348,29 +6336,25 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.TOXIC_CHAIN, 9)
|
new Ability(Abilities.TOXIC_CHAIN, 9)
|
||||||
.attr(PostAttackApplyStatusEffectAbAttr, false, 30, StatusEffect.TOXIC),
|
.attr(PostAttackApplyStatusEffectAbAttr, false, 30, StatusEffect.TOXIC),
|
||||||
new Ability(Abilities.EMBODY_ASPECT_TEAL, 9)
|
new Ability(Abilities.EMBODY_ASPECT_TEAL, 9)
|
||||||
.attr(PostBattleInitStatStageChangeAbAttr, [ Stat.SPD ], 1, true)
|
.attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.SPD ], 1)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr)
|
.attr(NoTransformAbilityAbAttr),
|
||||||
.partial(), // Ogerpon tera interactions
|
|
||||||
new Ability(Abilities.EMBODY_ASPECT_WELLSPRING, 9)
|
new Ability(Abilities.EMBODY_ASPECT_WELLSPRING, 9)
|
||||||
.attr(PostBattleInitStatStageChangeAbAttr, [ Stat.SPDEF ], 1, true)
|
.attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.SPDEF ], 1)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr)
|
.attr(NoTransformAbilityAbAttr),
|
||||||
.partial(), // Ogerpon tera interactions
|
|
||||||
new Ability(Abilities.EMBODY_ASPECT_HEARTHFLAME, 9)
|
new Ability(Abilities.EMBODY_ASPECT_HEARTHFLAME, 9)
|
||||||
.attr(PostBattleInitStatStageChangeAbAttr, [ Stat.ATK ], 1, true)
|
.attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.ATK ], 1)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr)
|
.attr(NoTransformAbilityAbAttr),
|
||||||
.partial(), // Ogerpon tera interactions
|
|
||||||
new Ability(Abilities.EMBODY_ASPECT_CORNERSTONE, 9)
|
new Ability(Abilities.EMBODY_ASPECT_CORNERSTONE, 9)
|
||||||
.attr(PostBattleInitStatStageChangeAbAttr, [ Stat.DEF ], 1, true)
|
.attr(PostTeraFormChangeStatChangeAbAttr, [ Stat.DEF ], 1)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr)
|
.attr(NoTransformAbilityAbAttr),
|
||||||
.partial(), // Ogerpon tera interactions
|
|
||||||
new Ability(Abilities.TERA_SHIFT, 9)
|
new Ability(Abilities.TERA_SHIFT, 9)
|
||||||
.attr(PostSummonFormChangeAbAttr, p => p.getFormKey() ? 0 : 1)
|
.attr(PostSummonFormChangeAbAttr, p => p.getFormKey() ? 0 : 1)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
|
@ -56,6 +56,7 @@ export enum ChargeAnim {
|
|||||||
export enum CommonAnim {
|
export enum CommonAnim {
|
||||||
USE_ITEM = 2000,
|
USE_ITEM = 2000,
|
||||||
HEALTH_UP,
|
HEALTH_UP,
|
||||||
|
TERASTALLIZE,
|
||||||
POISON = 2010,
|
POISON = 2010,
|
||||||
TOXIC,
|
TOXIC,
|
||||||
PARALYSIS,
|
PARALYSIS,
|
||||||
|
@ -779,7 +779,7 @@ export default class Move implements Localizable {
|
|||||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, null, typeChangeMovePowerMultiplier);
|
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, null, typeChangeMovePowerMultiplier);
|
||||||
|
|
||||||
const sourceTeraType = source.getTeraType();
|
const sourceTeraType = source.getTeraType();
|
||||||
if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !globalScene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) {
|
if (source.isTerastallized && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !globalScene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) {
|
||||||
power.value = 60;
|
power.value = 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,7 +594,7 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P
|
|||||||
console.error(`Failed to play animation for ${spriteKey}`, err);
|
console.error(`Failed to play animation for ${spriteKey}`, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()) });
|
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()), isTerastallized: tradedPokemon.isTerastallized });
|
||||||
sprite.setPipelineData("ignoreTimeTint", true);
|
sprite.setPipelineData("ignoreTimeTint", true);
|
||||||
sprite.setPipelineData("spriteKey", tradedPokemon.getSpriteKey());
|
sprite.setPipelineData("spriteKey", tradedPokemon.getSpriteKey());
|
||||||
sprite.setPipelineData("shiny", tradedPokemon.shiny);
|
sprite.setPipelineData("shiny", tradedPokemon.shiny);
|
||||||
@ -615,7 +615,7 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P
|
|||||||
console.error(`Failed to play animation for ${spriteKey}`, err);
|
console.error(`Failed to play animation for ${spriteKey}`, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()) });
|
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()), isTerastallized: tradedPokemon.isTerastallized });
|
||||||
sprite.setPipelineData("ignoreTimeTint", true);
|
sprite.setPipelineData("ignoreTimeTint", true);
|
||||||
sprite.setPipelineData("spriteKey", receivedPokemon.getSpriteKey());
|
sprite.setPipelineData("spriteKey", receivedPokemon.getSpriteKey());
|
||||||
sprite.setPipelineData("shiny", receivedPokemon.shiny);
|
sprite.setPipelineData("shiny", receivedPokemon.shiny);
|
||||||
|
@ -61,7 +61,7 @@ export function doPokemonTransformationSequence(previousPokemon: PlayerPokemon,
|
|||||||
console.error(`Failed to play animation for ${spriteKey}`, err);
|
console.error(`Failed to play animation for ${spriteKey}`, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(previousPokemon.getTeraType()) });
|
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(previousPokemon.getTeraType()), isTerastallized: previousPokemon.isTerastallized });
|
||||||
sprite.setPipelineData("ignoreTimeTint", true);
|
sprite.setPipelineData("ignoreTimeTint", true);
|
||||||
sprite.setPipelineData("spriteKey", previousPokemon.getSpriteKey());
|
sprite.setPipelineData("spriteKey", previousPokemon.getSpriteKey());
|
||||||
sprite.setPipelineData("shiny", previousPokemon.shiny);
|
sprite.setPipelineData("shiny", previousPokemon.shiny);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { PokemonFormChangeItemModifier, TerastallizeModifier } from "../modifier/modifier";
|
import { PokemonFormChangeItemModifier } from "../modifier/modifier";
|
||||||
import type Pokemon from "../field/pokemon";
|
import type Pokemon from "../field/pokemon";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import { MoveCategory, allMoves } from "./move";
|
import { MoveCategory, allMoves } from "./move";
|
||||||
import { Type } from "#enums/type";
|
|
||||||
import type { Constructor, nil } from "#app/utils";
|
import type { Constructor, nil } from "#app/utils";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
@ -398,23 +397,7 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger {
|
|||||||
* @extends SpeciesFormChangeTrigger
|
* @extends SpeciesFormChangeTrigger
|
||||||
*/
|
*/
|
||||||
export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger {
|
export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger {
|
||||||
/** The Tera type that triggers the form change */
|
description = i18next.t("pokemonEvolutions:Forms.tera" );
|
||||||
private teraType: Type;
|
|
||||||
|
|
||||||
constructor(teraType: Type) {
|
|
||||||
super();
|
|
||||||
this.teraType = teraType;
|
|
||||||
this.description = i18next.t("pokemonEvolutions:Forms.tera", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the associated Pokémon has the required Tera Shard that matches with the associated Tera type.
|
|
||||||
* @param {Pokemon} pokemon the Pokémon that is trying to do the form change
|
|
||||||
* @returns `true` if the Pokémon can change forms, `false` otherwise
|
|
||||||
*/
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
|
||||||
return !!globalScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id && m.teraType === this.teraType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -424,10 +407,6 @@ export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger {
|
|||||||
*/
|
*/
|
||||||
export class SpeciesFormChangeLapseTeraTrigger extends SpeciesFormChangeTrigger {
|
export class SpeciesFormChangeLapseTeraTrigger extends SpeciesFormChangeTrigger {
|
||||||
description = i18next.t("pokemonEvolutions:Forms.teraLapse");
|
description = i18next.t("pokemonEvolutions:Forms.teraLapse");
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
|
||||||
return !!globalScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -991,19 +970,19 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.OGERPON, "teal-mask", "wellspring-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.WELLSPRING_MASK)),
|
new SpeciesFormChange(Species.OGERPON, "teal-mask", "wellspring-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.WELLSPRING_MASK)),
|
||||||
new SpeciesFormChange(Species.OGERPON, "teal-mask", "hearthflame-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.HEARTHFLAME_MASK)),
|
new SpeciesFormChange(Species.OGERPON, "teal-mask", "hearthflame-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.HEARTHFLAME_MASK)),
|
||||||
new SpeciesFormChange(Species.OGERPON, "teal-mask", "cornerstone-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.CORNERSTONE_MASK)),
|
new SpeciesFormChange(Species.OGERPON, "teal-mask", "cornerstone-mask", new SpeciesFormChangeItemTrigger(FormChangeItem.CORNERSTONE_MASK)),
|
||||||
new SpeciesFormChange(Species.OGERPON, "teal-mask", "teal-mask-tera", new SpeciesFormChangeTeraTrigger(Type.GRASS)),
|
new SpeciesFormChange(Species.OGERPON, "teal-mask", "teal-mask-tera", new SpeciesFormChangeTeraTrigger(), true),
|
||||||
new SpeciesFormChange(Species.OGERPON, "teal-mask-tera", "teal-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.GRASS)),
|
new SpeciesFormChange(Species.OGERPON, "teal-mask-tera", "teal-mask", new SpeciesFormChangeLapseTeraTrigger(), true),
|
||||||
new SpeciesFormChange(Species.OGERPON, "wellspring-mask", "wellspring-mask-tera", new SpeciesFormChangeTeraTrigger(Type.WATER)),
|
new SpeciesFormChange(Species.OGERPON, "wellspring-mask", "wellspring-mask-tera", new SpeciesFormChangeTeraTrigger(), true),
|
||||||
new SpeciesFormChange(Species.OGERPON, "wellspring-mask-tera", "wellspring-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.WATER)),
|
new SpeciesFormChange(Species.OGERPON, "wellspring-mask-tera", "wellspring-mask", new SpeciesFormChangeLapseTeraTrigger(), true),
|
||||||
new SpeciesFormChange(Species.OGERPON, "hearthflame-mask", "hearthflame-mask-tera", new SpeciesFormChangeTeraTrigger(Type.FIRE)),
|
new SpeciesFormChange(Species.OGERPON, "hearthflame-mask", "hearthflame-mask-tera", new SpeciesFormChangeTeraTrigger(), true),
|
||||||
new SpeciesFormChange(Species.OGERPON, "hearthflame-mask-tera", "hearthflame-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.FIRE)),
|
new SpeciesFormChange(Species.OGERPON, "hearthflame-mask-tera", "hearthflame-mask", new SpeciesFormChangeLapseTeraTrigger(), true),
|
||||||
new SpeciesFormChange(Species.OGERPON, "cornerstone-mask", "cornerstone-mask-tera", new SpeciesFormChangeTeraTrigger(Type.ROCK)),
|
new SpeciesFormChange(Species.OGERPON, "cornerstone-mask", "cornerstone-mask-tera", new SpeciesFormChangeTeraTrigger(), true),
|
||||||
new SpeciesFormChange(Species.OGERPON, "cornerstone-mask-tera", "cornerstone-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.ROCK))
|
new SpeciesFormChange(Species.OGERPON, "cornerstone-mask-tera", "cornerstone-mask", new SpeciesFormChangeLapseTeraTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.TERAPAGOS]: [
|
[Species.TERAPAGOS]: [
|
||||||
new SpeciesFormChange(Species.TERAPAGOS, "", "terastal", new SpeciesFormChangeAbilityTrigger(), true),
|
new SpeciesFormChange(Species.TERAPAGOS, "", "terastal", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.TERAPAGOS, "terastal", "stellar", new SpeciesFormChangeTeraTrigger(Type.STELLAR)),
|
new SpeciesFormChange(Species.TERAPAGOS, "terastal", "stellar", new SpeciesFormChangeTeraTrigger(), true),
|
||||||
new SpeciesFormChange(Species.TERAPAGOS, "stellar", "terastal", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.STELLAR))
|
new SpeciesFormChange(Species.TERAPAGOS, "stellar", "terastal", new SpeciesFormChangeLapseTeraTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.GALAR_DARMANITAN]: [
|
[Species.GALAR_DARMANITAN]: [
|
||||||
new SpeciesFormChange(Species.GALAR_DARMANITAN, "", "zen", new SpeciesFormChangeAbilityTrigger(), true),
|
new SpeciesFormChange(Species.GALAR_DARMANITAN, "", "zen", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
|
@ -177,11 +177,51 @@ export const trainerPartyTemplates = {
|
|||||||
type PartyTemplateFunc = () => TrainerPartyTemplate;
|
type PartyTemplateFunc = () => TrainerPartyTemplate;
|
||||||
type PartyMemberFunc = (level: integer, strength: PartyMemberStrength) => EnemyPokemon;
|
type PartyMemberFunc = (level: integer, strength: PartyMemberStrength) => EnemyPokemon;
|
||||||
type GenModifiersFunc = (party: EnemyPokemon[]) => PersistentModifier[];
|
type GenModifiersFunc = (party: EnemyPokemon[]) => PersistentModifier[];
|
||||||
|
type GenAIFunc = (party: EnemyPokemon[]) => void;
|
||||||
|
|
||||||
export interface PartyMemberFuncs {
|
export interface PartyMemberFuncs {
|
||||||
[key: integer]: PartyMemberFunc
|
[key: integer]: PartyMemberFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum TeraAIMode {
|
||||||
|
NO_TERA,
|
||||||
|
INSTANT_TERA,
|
||||||
|
SMART_TERA
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores data and helper functions about a trainers AI options.
|
||||||
|
*/
|
||||||
|
export class TrainerAI {
|
||||||
|
public teraMode: TeraAIMode = TeraAIMode.NO_TERA;
|
||||||
|
public instantTeras: number[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param canTerastallize Whether this trainer is allowed to tera
|
||||||
|
*/
|
||||||
|
constructor(teraMode: TeraAIMode = TeraAIMode.NO_TERA) {
|
||||||
|
this.teraMode = teraMode;
|
||||||
|
this.instantTeras = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a trainer can tera
|
||||||
|
* @returns Whether this trainer can currently tera
|
||||||
|
*/
|
||||||
|
public canTerastallize() {
|
||||||
|
return this.teraMode !== TeraAIMode.NO_TERA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a pokemon on this AI to just instantly tera on first move used
|
||||||
|
* @param index The index of the pokemon to instantly tera
|
||||||
|
*/
|
||||||
|
public setInstantTera(index: number) {
|
||||||
|
this.teraMode = TeraAIMode.INSTANT_TERA;
|
||||||
|
this.instantTeras.push(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class TrainerConfig {
|
export class TrainerConfig {
|
||||||
public trainerType: TrainerType;
|
public trainerType: TrainerType;
|
||||||
public trainerTypeDouble: TrainerType;
|
public trainerTypeDouble: TrainerType;
|
||||||
@ -205,6 +245,7 @@ export class TrainerConfig {
|
|||||||
public doubleEncounterBgm: string;
|
public doubleEncounterBgm: string;
|
||||||
public victoryBgm: string;
|
public victoryBgm: string;
|
||||||
public genModifiersFunc: GenModifiersFunc;
|
public genModifiersFunc: GenModifiersFunc;
|
||||||
|
public genAIFuncs: GenAIFunc[] = [];
|
||||||
public modifierRewardFuncs: ModifierTypeFunc[] = [];
|
public modifierRewardFuncs: ModifierTypeFunc[] = [];
|
||||||
public partyTemplates: TrainerPartyTemplate[];
|
public partyTemplates: TrainerPartyTemplate[];
|
||||||
public partyTemplateFunc: PartyTemplateFunc;
|
public partyTemplateFunc: PartyTemplateFunc;
|
||||||
@ -214,6 +255,7 @@ export class TrainerConfig {
|
|||||||
public speciesFilter: PokemonSpeciesFilter;
|
public speciesFilter: PokemonSpeciesFilter;
|
||||||
public specialtyTypes: Type[] = [];
|
public specialtyTypes: Type[] = [];
|
||||||
public hasVoucher: boolean = false;
|
public hasVoucher: boolean = false;
|
||||||
|
public trainerAI: TrainerAI;
|
||||||
|
|
||||||
public encounterMessages: string[] = [];
|
public encounterMessages: string[] = [];
|
||||||
public victoryMessages: string[] = [];
|
public victoryMessages: string[] = [];
|
||||||
@ -229,6 +271,7 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
constructor(trainerType: TrainerType, allowLegendaries?: boolean) {
|
constructor(trainerType: TrainerType, allowLegendaries?: boolean) {
|
||||||
this.trainerType = trainerType;
|
this.trainerType = trainerType;
|
||||||
|
this.trainerAI = new TrainerAI();
|
||||||
this.name = Utils.toReadableString(TrainerType[this.getDerivedType()]);
|
this.name = Utils.toReadableString(TrainerType[this.getDerivedType()]);
|
||||||
this.battleBgm = "battle_trainer";
|
this.battleBgm = "battle_trainer";
|
||||||
this.mixedBattleBgm = "battle_trainer";
|
this.mixedBattleBgm = "battle_trainer";
|
||||||
@ -552,6 +595,37 @@ export class TrainerConfig {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setRandomTeraModifiers(count: () => integer): TrainerConfig {
|
||||||
|
this.genAIFuncs.push((party: EnemyPokemon[]) => {
|
||||||
|
const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i);
|
||||||
|
for (let t = 0; t < Math.min(count(), party.length); t++) {
|
||||||
|
const randomIndex = Utils.randSeedItem(partyMemberIndexes);
|
||||||
|
partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1);
|
||||||
|
if (this.specialtyTypes?.length) {
|
||||||
|
party[randomIndex].teraType = Utils.randSeedItem(this.specialtyTypes);
|
||||||
|
}
|
||||||
|
this.trainerAI.setInstantTera(randomIndex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
setInstantTera(index: integer): TrainerConfig {
|
||||||
|
this.trainerAI.setInstantTera(index);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, types?: Type[]): PersistentModifier[] {
|
||||||
|
// const ret: PersistentModifier[] = [];
|
||||||
|
// const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i);
|
||||||
|
// for (let t = 0; t < Math.min(count, party.length); t++) {
|
||||||
|
// const randomIndex = Utils.randSeedItem(partyMemberIndexes);
|
||||||
|
// partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1);
|
||||||
|
// ret.push(modifierTypes.TERA_SHARD().generateType([], [ Utils.randSeedItem(types ? types : party[randomIndex].getTypes()) ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); // TODO: is the bang correct?
|
||||||
|
// }
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
setEventModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig {
|
setEventModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig {
|
||||||
this.eventRewardFuncs = modifierTypeFuncs.map(func => () => {
|
this.eventRewardFuncs = modifierTypeFuncs.map(func => () => {
|
||||||
const modifierTypeFunc = func();
|
const modifierTypeFunc = func();
|
||||||
@ -846,10 +920,7 @@ export class TrainerConfig {
|
|||||||
this.setHasVoucher(true);
|
this.setHasVoucher(true);
|
||||||
this.setBattleBgm("battle_unova_gym");
|
this.setBattleBgm("battle_unova_gym");
|
||||||
this.setVictoryBgm("victory_gym");
|
this.setVictoryBgm("victory_gym");
|
||||||
this.setGenModifiersFunc(party => {
|
this.setRandomTeraModifiers(() => globalScene.currentBattle.waveIndex >= 100 ? 1 : 0);
|
||||||
const waveIndex = globalScene.currentBattle.waveIndex;
|
|
||||||
return getRandomTeraModifiers(party, waveIndex >= 100 ? 1 : 0, specialtyTypes.length ? specialtyTypes : undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -905,7 +976,7 @@ export class TrainerConfig {
|
|||||||
this.setHasVoucher(true);
|
this.setHasVoucher(true);
|
||||||
this.setBattleBgm("battle_unova_elite");
|
this.setBattleBgm("battle_unova_elite");
|
||||||
this.setVictoryBgm("victory_gym");
|
this.setVictoryBgm("victory_gym");
|
||||||
this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 2, specialtyTypes.length ? specialtyTypes : undefined));
|
this.setRandomTeraModifiers(() => 2);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -955,7 +1026,7 @@ export class TrainerConfig {
|
|||||||
this.setHasVoucher(true);
|
this.setHasVoucher(true);
|
||||||
this.setBattleBgm("battle_champion_alder");
|
this.setBattleBgm("battle_champion_alder");
|
||||||
this.setVictoryBgm("victory_champion");
|
this.setVictoryBgm("victory_champion");
|
||||||
this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 3));
|
this.setRandomTeraModifiers(() => 3);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -1205,17 +1276,6 @@ function getSpeciesFilterRandomPartyMemberFunc(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, types?: Type[]): PersistentModifier[] {
|
|
||||||
const ret: PersistentModifier[] = [];
|
|
||||||
const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i);
|
|
||||||
for (let t = 0; t < Math.min(count, party.length); t++) {
|
|
||||||
const randomIndex = Utils.randSeedItem(partyMemberIndexes);
|
|
||||||
partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1);
|
|
||||||
ret.push(modifierTypes.TERA_SHARD().generateType([], [ Utils.randSeedItem(types ? types : party[randomIndex].getTypes()) ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); // TODO: is the bang correct?
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
type SignatureSpecies = {
|
type SignatureSpecies = {
|
||||||
[key in string]: (Species | Species[])[];
|
[key in string]: (Species | Species[])[];
|
||||||
};
|
};
|
||||||
@ -1878,19 +1938,20 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
.setSpeciesFilter(species => species.baseTotal >= 540),
|
.setSpeciesFilter(species => species.baseTotal >= 540),
|
||||||
[TrainerType.RIVAL_4]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_2").setMixedBattleBgm("battle_rival_2").setPartyTemplates(trainerPartyTemplates.RIVAL_4)
|
[TrainerType.RIVAL_4]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_2").setMixedBattleBgm("battle_rival_2").setPartyTemplates(trainerPartyTemplates.RIVAL_4)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
|
||||||
(p => p.abilityIndex = 0)))
|
(p => {
|
||||||
|
p.abilityIndex = 0;
|
||||||
|
p.teraType = p.species.type1;
|
||||||
|
})))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
|
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
|
||||||
.setSpeciesFilter(species => species.baseTotal >= 540)
|
.setSpeciesFilter(species => species.baseTotal >= 540)
|
||||||
.setGenModifiersFunc(party => {
|
.setInstantTera(0),
|
||||||
const starter = party[0];
|
|
||||||
return [ modifierTypes.TERA_SHARD().generateType([], [ starter.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; // TODO: is the bang correct?
|
|
||||||
}),
|
|
||||||
[TrainerType.RIVAL_5]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_5)
|
[TrainerType.RIVAL_5]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_5)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
|
||||||
p => {
|
p => {
|
||||||
p.setBoss(true, 2);
|
p.setBoss(true, 2);
|
||||||
p.abilityIndex = 0;
|
p.abilityIndex = 0;
|
||||||
|
p.teraType = p.species.type1;
|
||||||
}))
|
}))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
|
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
|
||||||
@ -1901,15 +1962,13 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
p.shiny = true;
|
p.shiny = true;
|
||||||
p.variant = 1;
|
p.variant = 1;
|
||||||
}))
|
}))
|
||||||
.setGenModifiersFunc(party => {
|
.setInstantTera(0),
|
||||||
const starter = party[0];
|
|
||||||
return [ modifierTypes.TERA_SHARD().generateType([], [ starter.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; //TODO: is the bang correct?
|
|
||||||
}),
|
|
||||||
[TrainerType.RIVAL_6]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm("final").setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_6)
|
[TrainerType.RIVAL_6]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm("final").setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_6)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
|
||||||
p => {
|
p => {
|
||||||
p.setBoss(true, 3);
|
p.setBoss(true, 3);
|
||||||
p.abilityIndex = 0;
|
p.abilityIndex = 0;
|
||||||
|
p.teraType = p.species.type1;
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
}))
|
}))
|
||||||
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true,
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true,
|
||||||
@ -1928,10 +1987,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
p.formIndex = 1; // Mega Rayquaza
|
p.formIndex = 1; // Mega Rayquaza
|
||||||
p.generateName();
|
p.generateName();
|
||||||
}))
|
}))
|
||||||
.setGenModifiersFunc(party => {
|
.setInstantTera(0),
|
||||||
const starter = party[0];
|
|
||||||
return [ modifierTypes.TERA_SHARD().generateType([], [ starter.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; // TODO: is the bang correct?
|
|
||||||
}),
|
|
||||||
|
|
||||||
[TrainerType.ROCKET_BOSS_GIOVANNI_1]: new TrainerConfig(t = TrainerType.ROCKET_BOSS_GIOVANNI_1).setName("Giovanni").initForEvilTeamLeader("Rocket Boss", []).setMixedBattleBgm("battle_rocket_boss").setVictoryBgm("victory_team_plasma")
|
[TrainerType.ROCKET_BOSS_GIOVANNI_1]: new TrainerConfig(t = TrainerType.ROCKET_BOSS_GIOVANNI_1).setName("Giovanni").initForEvilTeamLeader("Rocket Boss", []).setMixedBattleBgm("battle_rocket_boss").setVictoryBgm("victory_team_plasma")
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PERSIAN, Species.ALOLA_PERSIAN ], TrainerSlot.TRAINER, true, p => {
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PERSIAN, Species.ALOLA_PERSIAN ], TrainerSlot.TRAINER, true, p => {
|
||||||
@ -2354,10 +2410,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
p.pokeball = PokeballType.ULTRA_BALL;
|
p.pokeball = PokeballType.ULTRA_BALL;
|
||||||
p.generateName();
|
p.generateName();
|
||||||
}))
|
}))
|
||||||
.setGenModifiersFunc(party => {
|
.setInstantTera(4),
|
||||||
const teraPokemon = party[4];
|
|
||||||
return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; //TODO: is the bang correct?
|
|
||||||
}),
|
|
||||||
[TrainerType.PENNY_2]: new TrainerConfig(++t).setName("Cassiopeia").initForEvilTeamLeader("Star Boss", [], true).setMixedBattleBgm("battle_star_boss").setVictoryBgm("victory_team_plasma")
|
[TrainerType.PENNY_2]: new TrainerConfig(++t).setName("Cassiopeia").initForEvilTeamLeader("Star Boss", [], true).setMixedBattleBgm("battle_star_boss").setVictoryBgm("victory_team_plasma")
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SYLVEON ], TrainerSlot.TRAINER, true, p => {
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SYLVEON ], TrainerSlot.TRAINER, true, p => {
|
||||||
p.setBoss(true, 2);
|
p.setBoss(true, 2);
|
||||||
@ -2387,10 +2440,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
p.pokeball = PokeballType.MASTER_BALL;
|
p.pokeball = PokeballType.MASTER_BALL;
|
||||||
}))
|
}))
|
||||||
.setGenModifiersFunc(party => {
|
.setInstantTera(0),
|
||||||
const teraPokemon = party[0];
|
|
||||||
return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; //TODO: is the bang correct?
|
|
||||||
}),
|
|
||||||
[TrainerType.BUCK]: new TrainerConfig(++t).setName("Buck").initForStatTrainer([], true)
|
[TrainerType.BUCK]: new TrainerConfig(++t).setName("Buck").initForStatTrainer([], true)
|
||||||
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLAYDOL ], TrainerSlot.TRAINER, true, p => {
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLAYDOL ], TrainerSlot.TRAINER, true, p => {
|
||||||
p.setBoss(true, 3);
|
p.setBoss(true, 3);
|
||||||
|
@ -27,6 +27,9 @@ export default class PokemonSpriteSparkleHandler {
|
|||||||
if (!s.visible || (s.parentContainer instanceof Pokemon && !s.parentContainer.parentContainer)) {
|
if (!s.visible || (s.parentContainer instanceof Pokemon && !s.parentContainer.parentContainer)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (s.parentContainer instanceof Pokemon && !(s.parentContainer as Pokemon).isTerastallized) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const pokemon = s.parentContainer instanceof Pokemon ? s.parentContainer as Pokemon : null;
|
const pokemon = s.parentContainer instanceof Pokemon ? s.parentContainer as Pokemon : null;
|
||||||
const parent = (pokemon || s).parentContainer;
|
const parent = (pokemon || s).parentContainer;
|
||||||
const texture = s.texture;
|
const texture = s.texture;
|
||||||
|
@ -19,7 +19,7 @@ import { getTypeDamageMultiplier, getTypeRgb } from "#app/data/type";
|
|||||||
import { Type } from "#enums/type";
|
import { Type } from "#enums/type";
|
||||||
import { getLevelTotalExp } from "#app/data/exp";
|
import { getLevelTotalExp } from "#app/data/exp";
|
||||||
import { Stat, type PermanentStat, type BattleStat, type EffectiveStat, PERMANENT_STATS, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat";
|
import { Stat, type PermanentStat, type BattleStat, type EffectiveStat, PERMANENT_STATS, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat";
|
||||||
import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier, PokemonMultiHitModifier } from "#app/modifier/modifier";
|
import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier, PokemonMultiHitModifier } from "#app/modifier/modifier";
|
||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import { Gender } from "#app/data/gender";
|
import { Gender } from "#app/data/gender";
|
||||||
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
|
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
|
||||||
@ -46,7 +46,7 @@ import { DexAttr } from "#app/system/game-data";
|
|||||||
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
|
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
|
||||||
import { getNatureStatMultiplier } from "#app/data/nature";
|
import { getNatureStatMultiplier } from "#app/data/nature";
|
||||||
import type { SpeciesFormChange } from "#app/data/pokemon-forms";
|
import type { SpeciesFormChange } from "#app/data/pokemon-forms";
|
||||||
import { SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from "#app/data/pokemon-forms";
|
import { SpeciesFormChangeActiveTrigger, SpeciesFormChangeLapseTeraTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from "#app/data/pokemon-forms";
|
||||||
import { TerrainType } from "#app/data/terrain";
|
import { TerrainType } from "#app/data/terrain";
|
||||||
import type { TrainerSlot } from "#app/data/trainer-config";
|
import type { TrainerSlot } from "#app/data/trainer-config";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
@ -141,6 +141,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
public fusionGender: Gender;
|
public fusionGender: Gender;
|
||||||
public fusionLuck: integer;
|
public fusionLuck: integer;
|
||||||
public fusionCustomPokemonData: CustomPokemonData | null;
|
public fusionCustomPokemonData: CustomPokemonData | null;
|
||||||
|
public fusionTeraType: Type;
|
||||||
|
|
||||||
private summonDataPrimer: PokemonSummonData | null;
|
private summonDataPrimer: PokemonSummonData | null;
|
||||||
|
|
||||||
@ -238,6 +239,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.fusionGender = dataSource.fusionGender;
|
this.fusionGender = dataSource.fusionGender;
|
||||||
this.fusionLuck = dataSource.fusionLuck;
|
this.fusionLuck = dataSource.fusionLuck;
|
||||||
this.fusionCustomPokemonData = dataSource.fusionCustomPokemonData;
|
this.fusionCustomPokemonData = dataSource.fusionCustomPokemonData;
|
||||||
|
this.fusionTeraType = dataSource.teraType;
|
||||||
this.usedTMs = dataSource.usedTMs ?? [];
|
this.usedTMs = dataSource.usedTMs ?? [];
|
||||||
this.customPokemonData = new CustomPokemonData(dataSource.customPokemonData);
|
this.customPokemonData = new CustomPokemonData(dataSource.customPokemonData);
|
||||||
this.teraType = dataSource.teraType;
|
this.teraType = dataSource.teraType;
|
||||||
@ -329,7 +331,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
const getSprite = (hasShadow?: boolean) => {
|
const getSprite = (hasShadow?: boolean) => {
|
||||||
const ret = globalScene.addPokemonSprite(this, 0, 0, `pkmn__${this.isPlayer() ? "back__" : ""}sub`, undefined, true);
|
const ret = globalScene.addPokemonSprite(this, 0, 0, `pkmn__${this.isPlayer() ? "back__" : ""}sub`, undefined, true);
|
||||||
ret.setOrigin(0.5, 1);
|
ret.setOrigin(0.5, 1);
|
||||||
ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, teraColor: getTypeRgb(this.getTeraType()) });
|
ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, teraColor: getTypeRgb(this.getTeraType()), isTerastallized: this.isTerastallized });
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -697,7 +699,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateSpritePipelineData(): void {
|
updateSpritePipelineData(): void {
|
||||||
[ this.getSprite(), this.getTintSprite() ].filter(s => !!s).map(s => s.pipelineData["teraColor"] = getTypeRgb(this.getTeraType()));
|
[ this.getSprite(), this.getTintSprite() ].filter(s => !!s).map(s => {
|
||||||
|
s.pipelineData["teraColor"] = getTypeRgb(this.getTeraType());
|
||||||
|
s.pipelineData["isTerastallized"] = this.isTerastallized;
|
||||||
|
});
|
||||||
this.updateInfo(true);
|
this.updateInfo(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1255,7 +1260,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
if (includeTeraType && this.isTerastallized) {
|
if (includeTeraType && this.isTerastallized) {
|
||||||
const teraType = this.getTeraType();
|
const teraType = this.getTeraType();
|
||||||
if (teraType !== Type.UNKNOWN && !(forDefend && teraType === Type.STELLAR)) { // Stellar tera uses its original types defensively
|
if (this.isTerastallized && !(forDefend && teraType === Type.STELLAR)) { // Stellar tera uses its original types defensively
|
||||||
types.push(teraType);
|
types.push(teraType);
|
||||||
if (forDefend) {
|
if (forDefend) {
|
||||||
return types;
|
return types;
|
||||||
@ -1561,18 +1566,28 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @returns the pokemon's current tera {@linkcode Type}, or `Type.UNKNOWN` if the pokemon is not terastallized
|
* @returns the pokemon's current tera {@linkcode Type}, or `Type.UNKNOWN` if the pokemon is not terastallized
|
||||||
*/
|
*/
|
||||||
getTeraType(): Type {
|
getTeraType(): Type {
|
||||||
return this.teraType;
|
if (this.species.speciesId === Species.TERAPAGOS || this.fusionSpecies?.speciesId === Species.TERAPAGOS) {
|
||||||
// this.scene can be undefined for a fainted mon in doubles
|
return Type.STELLAR;
|
||||||
if (this.scene !== undefined) {
|
} else if (this.species.speciesId === Species.OGERPON || this.fusionSpecies?.speciesId === Species.OGERPON) {
|
||||||
const teraModifier = globalScene.findModifier(m => m instanceof TerastallizeModifier
|
const ogerponForm = this.species.speciesId === Species.OGERPON ? this.formIndex : this.fusionFormIndex;
|
||||||
&& m.pokemonId === this.id && !!m.getBattlesLeft(), this.isPlayer()) as TerastallizeModifier;
|
switch (ogerponForm) {
|
||||||
// return teraType
|
case 0:
|
||||||
if (teraModifier) {
|
case 4:
|
||||||
return teraModifier.teraType;
|
return Type.GRASS;
|
||||||
|
case 1:
|
||||||
|
case 5:
|
||||||
|
return Type.WATER;
|
||||||
|
case 2:
|
||||||
|
case 6:
|
||||||
|
return Type.FIRE;
|
||||||
|
case 3:
|
||||||
|
case 7:
|
||||||
|
return Type.ROCK;
|
||||||
}
|
}
|
||||||
|
} else if (this.species.speciesId === Species.SHEDINJA || this.fusionSpecies?.speciesId === Species.SHEDINJA) {
|
||||||
|
return Type.BUG;
|
||||||
}
|
}
|
||||||
// if scene is undefined, or if teraModifier is considered false, then return unknown type
|
return this.teraType;
|
||||||
return Type.UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public isGrounded(): boolean {
|
public isGrounded(): boolean {
|
||||||
@ -2751,7 +2766,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
stabMultiplier.value += 0.5;
|
stabMultiplier.value += 0.5;
|
||||||
}
|
}
|
||||||
applyMoveAttrs(CombinedPledgeStabBoostAttr, source, this, move, stabMultiplier);
|
applyMoveAttrs(CombinedPledgeStabBoostAttr, source, this, move, stabMultiplier);
|
||||||
if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === moveType) {
|
if (source.isTerastallized && sourceTeraType === moveType) {
|
||||||
stabMultiplier.value += 0.5;
|
stabMultiplier.value += 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3781,7 +3796,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
resetBattleData(): void {
|
resetBattleData(): void {
|
||||||
this.battleData = new PokemonBattleData();
|
this.battleData = new PokemonBattleData();
|
||||||
this.isTerastallized = true;
|
const wasTerastallized = this.isTerastallized;
|
||||||
|
this.isTerastallized = false;
|
||||||
|
if (wasTerastallized) {
|
||||||
|
this.updateSpritePipelineData();
|
||||||
|
globalScene.triggerPokemonFormChange(this, SpeciesFormChangeLapseTeraTrigger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resetBattleSummonData(): void {
|
resetBattleSummonData(): void {
|
||||||
@ -4544,6 +4564,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
newPokemon.fusionVariant = this.fusionVariant;
|
newPokemon.fusionVariant = this.fusionVariant;
|
||||||
newPokemon.fusionGender = this.fusionGender;
|
newPokemon.fusionGender = this.fusionGender;
|
||||||
newPokemon.fusionLuck = this.fusionLuck;
|
newPokemon.fusionLuck = this.fusionLuck;
|
||||||
|
newPokemon.fusionTeraType = this.teraType;
|
||||||
newPokemon.usedTMs = this.usedTMs;
|
newPokemon.usedTMs = this.usedTMs;
|
||||||
|
|
||||||
globalScene.getPlayerParty().push(newPokemon);
|
globalScene.getPlayerParty().push(newPokemon);
|
||||||
@ -4715,6 +4736,7 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
public aiType: AiType;
|
public aiType: AiType;
|
||||||
public bossSegments: integer;
|
public bossSegments: integer;
|
||||||
public bossSegmentIndex: integer;
|
public bossSegmentIndex: integer;
|
||||||
|
public initialTeamIndex: integer;
|
||||||
/** To indicate if the instance was populated with a dataSource -> e.g. loaded & populated from session data */
|
/** To indicate if the instance was populated with a dataSource -> e.g. loaded & populated from session data */
|
||||||
public readonly isPopulatedFromDataSource: boolean;
|
public readonly isPopulatedFromDataSource: boolean;
|
||||||
|
|
||||||
@ -4724,6 +4746,7 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
undefined, dataSource ? dataSource.nature : undefined, dataSource);
|
undefined, dataSource ? dataSource.nature : undefined, dataSource);
|
||||||
|
|
||||||
this.trainerSlot = trainerSlot;
|
this.trainerSlot = trainerSlot;
|
||||||
|
this.initialTeamIndex = globalScene.currentBattle.enemyParty.length;
|
||||||
this.isPopulatedFromDataSource = !!dataSource; // if a dataSource is provided, then it was populated from dataSource
|
this.isPopulatedFromDataSource = !!dataSource; // if a dataSource is provided, then it was populated from dataSource
|
||||||
if (boss) {
|
if (boss) {
|
||||||
this.setBoss(boss, dataSource?.bossSegments);
|
this.setBoss(boss, dataSource?.bossSegments);
|
||||||
|
@ -11,7 +11,8 @@ import {
|
|||||||
TrainerSlot,
|
TrainerSlot,
|
||||||
trainerConfigs,
|
trainerConfigs,
|
||||||
trainerPartyTemplates,
|
trainerPartyTemplates,
|
||||||
signatureSpecies
|
signatureSpecies,
|
||||||
|
TeraAIMode
|
||||||
} from "#app/data/trainer-config";
|
} from "#app/data/trainer-config";
|
||||||
import type { EnemyPokemon } from "#app/field/pokemon";
|
import type { EnemyPokemon } from "#app/field/pokemon";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
@ -36,6 +37,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
public partyTemplateIndex: integer;
|
public partyTemplateIndex: integer;
|
||||||
public name: string;
|
public name: string;
|
||||||
public partnerName: string;
|
public partnerName: string;
|
||||||
|
public originalIndexes: { [key: number]: number } = {};
|
||||||
|
|
||||||
constructor(trainerType: TrainerType, variant: TrainerVariant, partyTemplateIndex?: integer, name?: string, partnerName?: string, trainerConfigOverride?: TrainerConfig) {
|
constructor(trainerType: TrainerType, variant: TrainerVariant, partyTemplateIndex?: integer, name?: string, partnerName?: string, trainerConfigOverride?: TrainerConfig) {
|
||||||
super(globalScene, -72, 80);
|
super(globalScene, -72, 80);
|
||||||
@ -546,6 +548,13 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
genAI(party: EnemyPokemon[]) {
|
||||||
|
if (this.config.genAIFuncs) {
|
||||||
|
this.config.genAIFuncs.forEach(f => f(party));
|
||||||
|
}
|
||||||
|
console.log("Generated AI funcs");
|
||||||
|
}
|
||||||
|
|
||||||
loadAssets(): Promise<void> {
|
loadAssets(): Promise<void> {
|
||||||
return this.config.loadAssets(this.variant);
|
return this.config.loadAssets(this.variant);
|
||||||
}
|
}
|
||||||
@ -667,4 +676,13 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shouldTera(pokemon: EnemyPokemon): boolean {
|
||||||
|
if (this.config.trainerAI.teraMode === TeraAIMode.INSTANT_TERA) {
|
||||||
|
if (!pokemon.isTerastallized && this.config.trainerAI.instantTeras.includes(pokemon.initialTeamIndex)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import { Type } from "#enums/type";
|
|||||||
import type { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
import type { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { AddPokeballModifier, AddVoucherModifier, AttackTypeBoosterModifier, BaseStatModifier, BerryModifier, BoostBugSpawnModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, CritBoosterModifier, DamageMoneyRewardModifier, DoubleBattleChanceBoosterModifier, EnemyAttackStatusEffectChanceModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, EvolutionItemModifier, EvolutionStatBoosterModifier, EvoTrackerModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, GigantamaxAccessModifier, HealingBoosterModifier, HealShopCostModifier, HiddenAbilityRateBoosterModifier, HitHealModifier, IvScannerModifier, LevelIncrementBoosterModifier, LockModifierTiersModifier, MapModifier, MegaEvolutionAccessModifier, MoneyInterestModifier, MoneyMultiplierModifier, MoneyRewardModifier, MultipleParticipantExpBonusModifier, PokemonAllMovePpRestoreModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, PokemonInstantReviveModifier, PokemonLevelIncrementModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PokemonNatureChangeModifier, PokemonNatureWeightModifier, PokemonPpRestoreModifier, PokemonPpUpModifier, PokemonStatusHealModifier, PreserveBerryModifier, RememberMoveModifier, ResetNegativeStatStageModifier, ShinyRateBoosterModifier, SpeciesCritBoosterModifier, SpeciesStatBoosterModifier, SurviveDamageModifier, SwitchEffectTransferModifier, TempCritBoosterModifier, TempStatStageBoosterModifier, TerastallizeAccessModifier, TerastallizeModifier, TmModifier, TurnHealModifier, TurnHeldItemTransferModifier, TurnStatusEffectModifier, type EnemyPersistentModifier, type Modifier, type PersistentModifier, TempExtraModifierModifier, CriticalCatchChanceBoosterModifier } from "#app/modifier/modifier";
|
import { AddPokeballModifier, AddVoucherModifier, AttackTypeBoosterModifier, BaseStatModifier, BerryModifier, BoostBugSpawnModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, CritBoosterModifier, DamageMoneyRewardModifier, DoubleBattleChanceBoosterModifier, EnemyAttackStatusEffectChanceModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, EvolutionItemModifier, EvolutionStatBoosterModifier, EvoTrackerModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, GigantamaxAccessModifier, HealingBoosterModifier, HealShopCostModifier, HiddenAbilityRateBoosterModifier, HitHealModifier, IvScannerModifier, LevelIncrementBoosterModifier, LockModifierTiersModifier, MapModifier, MegaEvolutionAccessModifier, MoneyInterestModifier, MoneyMultiplierModifier, MoneyRewardModifier, MultipleParticipantExpBonusModifier, PokemonAllMovePpRestoreModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, PokemonInstantReviveModifier, PokemonLevelIncrementModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PokemonNatureChangeModifier, PokemonNatureWeightModifier, PokemonPpRestoreModifier, PokemonPpUpModifier, PokemonStatusHealModifier, PreserveBerryModifier, RememberMoveModifier, ResetNegativeStatStageModifier, ShinyRateBoosterModifier, SpeciesCritBoosterModifier, SpeciesStatBoosterModifier, SurviveDamageModifier, SwitchEffectTransferModifier, TempCritBoosterModifier, TempStatStageBoosterModifier, TerastallizeAccessModifier, TerrastalizeModifier, TmModifier, TurnHealModifier, TurnHeldItemTransferModifier, TurnStatusEffectModifier, type EnemyPersistentModifier, type Modifier, type PersistentModifier, TempExtraModifierModifier, CriticalCatchChanceBoosterModifier } from "#app/modifier/modifier";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import { Unlockables } from "#app/system/unlockables";
|
import { Unlockables } from "#app/system/unlockables";
|
||||||
@ -19,7 +19,7 @@ import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#app/system
|
|||||||
import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler";
|
import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler";
|
||||||
import PartyUiHandler from "#app/ui/party-ui-handler";
|
import PartyUiHandler from "#app/ui/party-ui-handler";
|
||||||
import { getModifierTierTextTint } from "#app/ui/text";
|
import { getModifierTierTextTint } from "#app/ui/text";
|
||||||
import { formatMoney, getEnumKeys, getEnumValues, isNullOrUndefined, NumberHolder, padInt, randSeedInt, randSeedItem } from "#app/utils";
|
import { formatMoney, getEnumKeys, getEnumValues, isNullOrUndefined, NumberHolder, padInt, randSeedInt } from "#app/utils";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
@ -275,6 +275,36 @@ export class PokemonHeldItemModifierType extends PokemonModifierType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class TerastallizeModifierType extends PokemonModifierType {
|
||||||
|
private teraType: Type;
|
||||||
|
|
||||||
|
constructor(teraType: Type) {
|
||||||
|
super("", `${Type[teraType].toLowerCase()}_tera_shard`, (type, args) => new TerrastalizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType),
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
if ([ pokemon.species.speciesId, pokemon.fusionSpecies?.speciesId ].filter(s => s === Species.TERAPAGOS || s === Species.OGERPON || s === Species.SHEDINJA).length > 0) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"tera_shard");
|
||||||
|
|
||||||
|
this.teraType = teraType;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.TerastallizeModifierType.name", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) });
|
||||||
|
}
|
||||||
|
|
||||||
|
getDescription(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.TerastallizeModifierType.description", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) });
|
||||||
|
}
|
||||||
|
|
||||||
|
getPregenArgs(): any[] {
|
||||||
|
return [ this.teraType ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class PokemonHpRestoreModifierType extends PokemonModifierType {
|
export class PokemonHpRestoreModifierType extends PokemonModifierType {
|
||||||
protected restorePoints: integer;
|
protected restorePoints: integer;
|
||||||
protected restorePercent: integer;
|
protected restorePercent: integer;
|
||||||
@ -1192,28 +1222,6 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TerastallizeModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType {
|
|
||||||
private teraType: Type;
|
|
||||||
|
|
||||||
constructor(teraType: Type) {
|
|
||||||
super("", `${Type[teraType].toLowerCase()}_tera_shard`, (type, args) => new TerastallizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType), "tera_shard");
|
|
||||||
|
|
||||||
this.teraType = teraType;
|
|
||||||
}
|
|
||||||
|
|
||||||
get name(): string {
|
|
||||||
return i18next.t("modifierType:ModifierType.TerastallizeModifierType.name", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) });
|
|
||||||
}
|
|
||||||
|
|
||||||
getDescription(): string {
|
|
||||||
return i18next.t("modifierType:ModifierType.TerastallizeModifierType.description", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) });
|
|
||||||
}
|
|
||||||
|
|
||||||
getPregenArgs(): any[] {
|
|
||||||
return [ this.teraType ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemModifierType {
|
export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemModifierType {
|
||||||
private chancePercent: integer;
|
private chancePercent: integer;
|
||||||
|
|
||||||
@ -1469,14 +1477,7 @@ export const modifierTypes = {
|
|||||||
if (!globalScene.getModifiers(TerastallizeAccessModifier).length) {
|
if (!globalScene.getModifiers(TerastallizeAccessModifier).length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let type: Type;
|
return new TerastallizeModifierType(randSeedInt(64) ? randSeedInt(18) as Type : Type.STELLAR);
|
||||||
if (!randSeedInt(3)) {
|
|
||||||
const partyMemberTypes = party.map(p => p.getTypes(false, false, true)).flat();
|
|
||||||
type = randSeedItem(partyMemberTypes);
|
|
||||||
} else {
|
|
||||||
type = randSeedInt(64) ? randSeedInt(18) as Type : Type.STELLAR;
|
|
||||||
}
|
|
||||||
return new TerastallizeModifierType(type);
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
BERRY: () => new ModifierTypeGenerator((_party: Pokemon[], pregenArgs?: any[]) => {
|
BERRY: () => new ModifierTypeGenerator((_party: Pokemon[], pregenArgs?: any[]) => {
|
||||||
|
@ -3,16 +3,16 @@ import { getBerryEffectFunc, getBerryPredicate } from "#app/data/berry";
|
|||||||
import { getLevelTotalExp } from "#app/data/exp";
|
import { getLevelTotalExp } from "#app/data/exp";
|
||||||
import { allMoves } from "#app/data/move";
|
import { allMoves } from "#app/data/move";
|
||||||
import { MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball";
|
import { MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball";
|
||||||
import { type FormChangeItem, SpeciesFormChangeItemTrigger, SpeciesFormChangeLapseTeraTrigger, SpeciesFormChangeTeraTrigger } from "#app/data/pokemon-forms";
|
import { type FormChangeItem, SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms";
|
||||||
import { getStatusEffectHealText } from "#app/data/status-effect";
|
import { getStatusEffectHealText } from "#app/data/status-effect";
|
||||||
import Pokemon, { type PlayerPokemon } from "#app/field/pokemon";
|
import type { PlayerPokemon } from "#app/field/pokemon";
|
||||||
|
import Pokemon from "#app/field/pokemon";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import { EvolutionPhase } from "#app/phases/evolution-phase";
|
import { EvolutionPhase } from "#app/phases/evolution-phase";
|
||||||
import { LearnMovePhase, LearnMoveType } from "#app/phases/learn-move-phase";
|
import { LearnMovePhase, LearnMoveType } from "#app/phases/learn-move-phase";
|
||||||
import { LevelUpPhase } from "#app/phases/level-up-phase";
|
import { LevelUpPhase } from "#app/phases/level-up-phase";
|
||||||
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
||||||
import { achvs } from "#app/system/achv";
|
|
||||||
import type { VoucherType } from "#app/system/voucher";
|
import type { VoucherType } from "#app/system/voucher";
|
||||||
import { Command } from "#app/ui/command-ui-handler";
|
import { Command } from "#app/ui/command-ui-handler";
|
||||||
import { addTextObject, TextStyle } from "#app/ui/text";
|
import { addTextObject, TextStyle } from "#app/ui/text";
|
||||||
@ -25,7 +25,7 @@ import type { PokeballType } from "#enums/pokeball";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { type PermanentStat, type TempBattleStat, BATTLE_STATS, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
import { type PermanentStat, type TempBattleStat, BATTLE_STATS, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import { Type } from "#enums/type";
|
import type { Type } from "#enums/type";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { type DoubleBattleChanceBoosterModifierType, type EvolutionItemModifierType, type FormChangeItemModifierType, type ModifierOverride, type ModifierType, type PokemonBaseStatTotalModifierType, type PokemonExpBoosterModifierType, type PokemonFriendshipBoosterModifierType, type PokemonMoveAccuracyBoosterModifierType, type PokemonMultiHitModifierType, type TerastallizeModifierType, type TmModifierType, getModifierType, ModifierPoolType, ModifierTypeGenerator, modifierTypes, PokemonHeldItemModifierType } from "./modifier-type";
|
import { type DoubleBattleChanceBoosterModifierType, type EvolutionItemModifierType, type FormChangeItemModifierType, type ModifierOverride, type ModifierType, type PokemonBaseStatTotalModifierType, type PokemonExpBoosterModifierType, type PokemonFriendshipBoosterModifierType, type PokemonMoveAccuracyBoosterModifierType, type PokemonMultiHitModifierType, type TerastallizeModifierType, type TmModifierType, getModifierType, ModifierPoolType, ModifierTypeGenerator, modifierTypes, PokemonHeldItemModifierType } from "./modifier-type";
|
||||||
import { Color, ShadowColor } from "#enums/color";
|
import { Color, ShadowColor } from "#enums/color";
|
||||||
@ -786,72 +786,6 @@ export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TerastallizeModifier extends LapsingPokemonHeldItemModifier {
|
|
||||||
public override type: TerastallizeModifierType;
|
|
||||||
public teraType: Type;
|
|
||||||
public isTransferable: boolean = false;
|
|
||||||
|
|
||||||
constructor(type: TerastallizeModifierType, pokemonId: number, teraType: Type, battlesLeft?: number, stackCount?: number) {
|
|
||||||
super(type, pokemonId, battlesLeft || 10, stackCount);
|
|
||||||
|
|
||||||
this.teraType = teraType;
|
|
||||||
}
|
|
||||||
|
|
||||||
matchType(modifier: Modifier): boolean {
|
|
||||||
if (modifier instanceof TerastallizeModifier && modifier.teraType === this.teraType) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
clone(): TerastallizeModifier {
|
|
||||||
return new TerastallizeModifier(this.type, this.pokemonId, this.teraType, this.battlesLeft, this.stackCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
getArgs(): any[] {
|
|
||||||
return [ this.pokemonId, this.teraType, this.battlesLeft ];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies the {@linkcode TerastallizeModifier} to the specified {@linkcode Pokemon}.
|
|
||||||
* @param pokemon the {@linkcode Pokemon} to be terastallized
|
|
||||||
* @returns always `true`
|
|
||||||
*/
|
|
||||||
override apply(pokemon: Pokemon): boolean {
|
|
||||||
if (pokemon.isPlayer()) {
|
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeTeraTrigger);
|
|
||||||
globalScene.validateAchv(achvs.TERASTALLIZE);
|
|
||||||
if (this.teraType === Type.STELLAR) {
|
|
||||||
globalScene.validateAchv(achvs.STELLAR_TERASTALLIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pokemon.updateSpritePipelineData();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Triggers {@linkcode LapsingPokemonHeldItemModifier.lapse} and if it returns `0` a form change is triggered.
|
|
||||||
* @param pokemon THe {@linkcode Pokemon} to be terastallized
|
|
||||||
* @returns the result of {@linkcode LapsingPokemonHeldItemModifier.lapse}
|
|
||||||
*/
|
|
||||||
public override lapse(pokemon: Pokemon): boolean {
|
|
||||||
const ret = super.lapse(pokemon);
|
|
||||||
if (!ret) {
|
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeLapseTeraTrigger);
|
|
||||||
pokemon.updateSpritePipelineData();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
getScoreMultiplier(): number {
|
|
||||||
return 1.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
getMaxHeldItemCount(pokemon: Pokemon): number {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifier used for held items, specifically vitamins like Carbos, Hp Up, etc., that
|
* Modifier used for held items, specifically vitamins like Carbos, Hp Up, etc., that
|
||||||
* increase the value of a given {@linkcode PermanentStat}.
|
* increase the value of a given {@linkcode PermanentStat}.
|
||||||
@ -2022,6 +1956,36 @@ export abstract class ConsumablePokemonModifier extends ConsumableModifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class TerrastalizeModifier extends ConsumablePokemonModifier {
|
||||||
|
public override type: TerastallizeModifierType;
|
||||||
|
public teraType: Type;
|
||||||
|
|
||||||
|
constructor(type: TerastallizeModifierType, pokemonId: number, teraType: Type) {
|
||||||
|
super(type, pokemonId);
|
||||||
|
|
||||||
|
this.teraType = teraType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if {@linkcode TerrastalizeModifier} should be applied
|
||||||
|
* @param playerPokemon The {@linkcode PlayerPokemon} that consumes the item
|
||||||
|
* @returns `true` if the {@linkcode TerrastalizeModifier} should be applied
|
||||||
|
*/
|
||||||
|
override shouldApply(playerPokemon?: PlayerPokemon): boolean {
|
||||||
|
return super.shouldApply(playerPokemon) && [ playerPokemon?.species.speciesId, playerPokemon?.fusionSpecies?.speciesId ].filter(s => s === Species.TERAPAGOS || s === Species.OGERPON || s === Species.SHEDINJA).length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode TerrastalizeModifier}
|
||||||
|
* @param pokemon The {@linkcode PlayerPokemon} that consumes the item
|
||||||
|
* @returns `true` if hp was restored
|
||||||
|
*/
|
||||||
|
override apply(pokemon: Pokemon): boolean {
|
||||||
|
pokemon.teraType = this.teraType;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class PokemonHpRestoreModifier extends ConsumablePokemonModifier {
|
export class PokemonHpRestoreModifier extends ConsumablePokemonModifier {
|
||||||
private restorePoints: number;
|
private restorePoints: number;
|
||||||
private restorePercent: number;
|
private restorePercent: number;
|
||||||
|
@ -118,9 +118,8 @@ export class CommandPhase extends FieldPhase {
|
|||||||
let success: boolean = false;
|
let success: boolean = false;
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case Command.FIGHT:
|
|
||||||
case Command.TERA:
|
case Command.TERA:
|
||||||
console.log("Fight From Command", command);
|
case Command.FIGHT:
|
||||||
let useStruggle = false;
|
let useStruggle = false;
|
||||||
const turnMove: TurnMove | undefined = (args.length === 2 ? (args[1] as TurnMove) : undefined);
|
const turnMove: TurnMove | undefined = (args.length === 2 ? (args[1] as TurnMove) : undefined);
|
||||||
if (cursor === -1 ||
|
if (cursor === -1 ||
|
||||||
@ -139,6 +138,7 @@ export class CommandPhase extends FieldPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args };
|
const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args };
|
||||||
|
const preTurnCommand: TurnCommand = { command: command, targets: [ this.fieldIndex ], skip: command === Command.FIGHT };
|
||||||
const moveTargets: MoveTargetSet = turnMove === undefined ? getMoveTargets(playerPokemon, moveId) : { targets: turnMove.targets, multiple: turnMove.targets.length > 1 };
|
const moveTargets: MoveTargetSet = turnMove === undefined ? getMoveTargets(playerPokemon, moveId) : { targets: turnMove.targets, multiple: turnMove.targets.length > 1 };
|
||||||
if (!moveId) {
|
if (!moveId) {
|
||||||
turnCommand.targets = [ this.fieldIndex ];
|
turnCommand.targets = [ this.fieldIndex ];
|
||||||
@ -154,6 +154,7 @@ export class CommandPhase extends FieldPhase {
|
|||||||
} else {
|
} else {
|
||||||
globalScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
|
globalScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
|
||||||
}
|
}
|
||||||
|
globalScene.currentBattle.preTurnCommands[this.fieldIndex] = preTurnCommand;
|
||||||
globalScene.currentBattle.turnCommands[this.fieldIndex] = turnCommand;
|
globalScene.currentBattle.turnCommands[this.fieldIndex] = turnCommand;
|
||||||
success = true;
|
success = true;
|
||||||
} else if (cursor < playerPokemon.getMoveset().length) {
|
} else if (cursor < playerPokemon.getMoveset().length) {
|
||||||
|
@ -81,6 +81,10 @@ export class EnemyCommandPhase extends FieldPhase {
|
|||||||
/** Select a move to use (and a target to use it against, if applicable) */
|
/** Select a move to use (and a target to use it against, if applicable) */
|
||||||
const nextMove = enemyPokemon.getNextMove();
|
const nextMove = enemyPokemon.getNextMove();
|
||||||
|
|
||||||
|
if (trainer && trainer.shouldTera(enemyPokemon)) {
|
||||||
|
globalScene.currentBattle.preTurnCommands[this.fieldIndex + BattlerIndex.ENEMY] = { command: Command.TERA };
|
||||||
|
}
|
||||||
|
|
||||||
globalScene.currentBattle.turnCommands[this.fieldIndex + BattlerIndex.ENEMY] =
|
globalScene.currentBattle.turnCommands[this.fieldIndex + BattlerIndex.ENEMY] =
|
||||||
{ command: Command.FIGHT, move: nextMove, skip: this.skipTurn };
|
{ command: Command.FIGHT, move: nextMove, skip: this.skipTurn };
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ export class EvolutionPhase extends Phase {
|
|||||||
console.error(`Failed to play animation for ${spriteKey}`, err);
|
console.error(`Failed to play animation for ${spriteKey}`, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) });
|
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()), isTerastallized: this.pokemon.isTerastallized });
|
||||||
sprite.setPipelineData("ignoreTimeTint", true);
|
sprite.setPipelineData("ignoreTimeTint", true);
|
||||||
sprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey());
|
sprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey());
|
||||||
sprite.setPipelineData("shiny", this.pokemon.shiny);
|
sprite.setPipelineData("shiny", this.pokemon.shiny);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { SemiInvulnerableTag } from "#app/data/battler-tags";
|
import { SemiInvulnerableTag } from "#app/data/battler-tags";
|
||||||
import type { SpeciesFormChange } from "#app/data/pokemon-forms";
|
import type { SpeciesFormChange } from "#app/data/pokemon-forms";
|
||||||
import { getSpeciesFormChangeMessage } from "#app/data/pokemon-forms";
|
import { getSpeciesFormChangeMessage, SpeciesFormChangeTeraTrigger } from "#app/data/pokemon-forms";
|
||||||
import { getTypeRgb } from "#app/data/type";
|
import { getTypeRgb } from "#app/data/type";
|
||||||
import { BattleSpec } from "#app/enums/battle-spec";
|
import { BattleSpec } from "#app/enums/battle-spec";
|
||||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
||||||
@ -11,6 +11,7 @@ import { getPokemonNameWithAffix } from "#app/messages";
|
|||||||
import { BattlePhase } from "./battle-phase";
|
import { BattlePhase } from "./battle-phase";
|
||||||
import { MovePhase } from "./move-phase";
|
import { MovePhase } from "./move-phase";
|
||||||
import { PokemonHealPhase } from "./pokemon-heal-phase";
|
import { PokemonHealPhase } from "./pokemon-heal-phase";
|
||||||
|
import { applyAbAttrs, PostTeraFormChangeStatChangeAbAttr } from "#app/data/ability";
|
||||||
|
|
||||||
export class QuietFormChangePhase extends BattlePhase {
|
export class QuietFormChangePhase extends BattlePhase {
|
||||||
protected pokemon: Pokemon;
|
protected pokemon: Pokemon;
|
||||||
@ -51,7 +52,7 @@ export class QuietFormChangePhase extends BattlePhase {
|
|||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
console.error(`Failed to play animation for ${spriteKey}`, err);
|
console.error(`Failed to play animation for ${spriteKey}`, err);
|
||||||
}
|
}
|
||||||
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) });
|
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()), isTerastallized: this.pokemon.isTerastallized });
|
||||||
[ "spriteColors", "fusionSpriteColors" ].map(k => {
|
[ "spriteColors", "fusionSpriteColors" ].map(k => {
|
||||||
if (this.pokemon.summonData?.speciesForm) {
|
if (this.pokemon.summonData?.speciesForm) {
|
||||||
k += "Base";
|
k += "Base";
|
||||||
@ -145,6 +146,9 @@ export class QuietFormChangePhase extends BattlePhase {
|
|||||||
movePhase.cancel();
|
movePhase.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.formChange.trigger instanceof SpeciesFormChangeTeraTrigger) {
|
||||||
|
applyAbAttrs(PostTeraFormChangeStatChangeAbAttr, this.pokemon, null);
|
||||||
|
}
|
||||||
|
|
||||||
super.end();
|
super.end();
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,9 @@ import { BattlePhase } from "./battle-phase";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { Type } from "#app/enums/type";
|
import { Type } from "#app/enums/type";
|
||||||
|
import { achvs } from "#app/system/achv";
|
||||||
|
import { SpeciesFormChangeTeraTrigger } from "#app/data/pokemon-forms";
|
||||||
|
import { CommonAnim, CommonBattleAnim } from "#app/data/battle-anims";
|
||||||
|
|
||||||
export class TeraPhase extends BattlePhase {
|
export class TeraPhase extends BattlePhase {
|
||||||
public pokemon: Pokemon;
|
public pokemon: Pokemon;
|
||||||
@ -19,6 +22,17 @@ export class TeraPhase extends BattlePhase {
|
|||||||
|
|
||||||
console.log(this.pokemon.name, "terastallized to", Type[this.pokemon.teraType].toString()); // TODO: Improve log
|
console.log(this.pokemon.name, "terastallized to", Type[this.pokemon.teraType].toString()); // TODO: Improve log
|
||||||
|
|
||||||
|
// const parent = this.pokemon.parentContainer;
|
||||||
|
// // const texture = this.pokemon.getSprite().texture;
|
||||||
|
// // const [ width, height ] = [ texture.source[0].width, texture.source[0].height ];
|
||||||
|
// // const [ xOffset, yOffset ] = [ -this.pokemon.getSprite().originX * width, -s.originY * s.height ];
|
||||||
|
// const teraburst = globalScene.addFieldSprite(((this.pokemon?.x || 0)), ((this.pokemon?.y || 0)), "terastallize");
|
||||||
|
// teraburst.setName("sprite-terastallize");
|
||||||
|
// teraburst.play("terastallize");
|
||||||
|
// parent.add(teraburst);
|
||||||
|
// this.pokemon.scene.time.delayedCall(Utils.fixedInt(Math.floor((1000 / 12) * 13)), () => teraburst.destroy());
|
||||||
|
|
||||||
|
new CommonBattleAnim(CommonAnim.TERASTALLIZE, this.pokemon).play();
|
||||||
globalScene.queueMessage(getPokemonNameWithAffix(this.pokemon) + " terrastallized into a " + i18next.t(`pokemonInfo:Type.${Type[this.pokemon.teraType]}`) + " type!"); // TODO: Localize this
|
globalScene.queueMessage(getPokemonNameWithAffix(this.pokemon) + " terrastallized into a " + i18next.t(`pokemonInfo:Type.${Type[this.pokemon.teraType]}`) + " type!"); // TODO: Localize this
|
||||||
// this.scene.unshiftPhase(new CommonAnimPhase(this.scene, this.pokemon.getBattlerIndex(), undefined, CommonAnim.???));
|
// this.scene.unshiftPhase(new CommonAnimPhase(this.scene, this.pokemon.getBattlerIndex(), undefined, CommonAnim.???));
|
||||||
|
|
||||||
@ -28,6 +42,16 @@ export class TeraPhase extends BattlePhase {
|
|||||||
|
|
||||||
end() {
|
end() {
|
||||||
this.pokemon.isTerastallized = true;
|
this.pokemon.isTerastallized = true;
|
||||||
|
this.pokemon.updateSpritePipelineData();
|
||||||
|
|
||||||
|
globalScene.triggerPokemonFormChange(this.pokemon, SpeciesFormChangeTeraTrigger);
|
||||||
|
|
||||||
|
if (this.pokemon.isPlayer()) {
|
||||||
|
globalScene.validateAchv(achvs.TERASTALLIZE);
|
||||||
|
if (this.pokemon.teraType === Type.STELLAR) {
|
||||||
|
globalScene.validateAchv(achvs.STELLAR_TERASTALLIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
super.end();
|
super.end();
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import { BattlerIndex } from "#app/battle";
|
|||||||
import { TrickRoomTag } from "#app/data/arena-tag";
|
import { TrickRoomTag } from "#app/data/arena-tag";
|
||||||
import { SwitchType } from "#enums/switch-type";
|
import { SwitchType } from "#enums/switch-type";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { TeraPhase } from "./tera-phase";
|
||||||
|
|
||||||
export class TurnStartPhase extends FieldPhase {
|
export class TurnStartPhase extends FieldPhase {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -139,6 +140,20 @@ export class TurnStartPhase extends FieldPhase {
|
|||||||
|
|
||||||
let orderIndex = 0;
|
let orderIndex = 0;
|
||||||
|
|
||||||
|
for (const o of this.getSpeedOrder()) {
|
||||||
|
const pokemon = field[o];
|
||||||
|
const preTurnCommand = globalScene.currentBattle.preTurnCommands[o];
|
||||||
|
|
||||||
|
if (preTurnCommand?.skip) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (preTurnCommand?.command) {
|
||||||
|
case Command.TERA:
|
||||||
|
globalScene.pushPhase(new TeraPhase(pokemon));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const o of moveOrder) {
|
for (const o of moveOrder) {
|
||||||
|
|
||||||
const pokemon = field[o];
|
const pokemon = field[o];
|
||||||
|
@ -351,7 +351,7 @@ export default class SpritePipeline extends FieldSpritePipeline {
|
|||||||
|
|
||||||
const data = sprite.pipelineData;
|
const data = sprite.pipelineData;
|
||||||
const tone = data["tone"] as number[];
|
const tone = data["tone"] as number[];
|
||||||
const teraColor = data["teraColor"] as integer[] ?? [ 0, 0, 0 ];
|
const teraColor = (data["isTerastallized"] as boolean) ? (data["teraColor"] as integer[] ?? [ 0, 0, 0 ]) : [ 0, 0, 0 ];
|
||||||
const hasShadow = data["hasShadow"] as boolean;
|
const hasShadow = data["hasShadow"] as boolean;
|
||||||
const yShadowOffset = data["yShadowOffset"] as number;
|
const yShadowOffset = data["yShadowOffset"] as number;
|
||||||
const ignoreFieldPos = data["ignoreFieldPos"] as boolean;
|
const ignoreFieldPos = data["ignoreFieldPos"] as boolean;
|
||||||
|
@ -6,7 +6,7 @@ import { Abilities } from "#app/enums/abilities";
|
|||||||
import { Moves } from "#app/enums/moves";
|
import { Moves } from "#app/enums/moves";
|
||||||
import { Species } from "#app/enums/species";
|
import { Species } from "#app/enums/species";
|
||||||
import * as Messages from "#app/messages";
|
import * as Messages from "#app/messages";
|
||||||
import { TerastallizeModifier, overrideHeldItems } from "#app/modifier/modifier";
|
import { overrideHeldItems } from "#app/modifier/modifier";
|
||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
||||||
@ -40,7 +40,6 @@ describe("Moves - Type Effectiveness", () => {
|
|||||||
type: Phaser.HEADLESS,
|
type: Phaser.HEADLESS,
|
||||||
});
|
});
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
TerastallizeModifier.prototype.apply = (args) => true;
|
|
||||||
|
|
||||||
game.override.ability(Abilities.BALL_FETCH);
|
game.override.ability(Abilities.BALL_FETCH);
|
||||||
});
|
});
|
||||||
|
@ -324,9 +324,9 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
|
|||||||
this.lastTeraType = pokemon.getTeraType();
|
this.lastTeraType = pokemon.getTeraType();
|
||||||
|
|
||||||
this.teraIcon.setPositionRelative(this.nameText, nameTextWidth + this.genderText.displayWidth + 1, 2);
|
this.teraIcon.setPositionRelative(this.nameText, nameTextWidth + this.genderText.displayWidth + 1, 2);
|
||||||
this.teraIcon.setVisible(this.lastTeraType !== Type.UNKNOWN);
|
this.teraIcon.setVisible(pokemon.isTerastallized);
|
||||||
this.teraIcon.on("pointerover", () => {
|
this.teraIcon.on("pointerover", () => {
|
||||||
if (this.lastTeraType !== Type.UNKNOWN) {
|
if (pokemon.isTerastallized) {
|
||||||
globalScene.ui.showTooltip("", i18next.t("fightUiHandler:teraHover", { type: i18next.t(`pokemonInfo:Type.${Type[this.lastTeraType]}`) }));
|
globalScene.ui.showTooltip("", i18next.t("fightUiHandler:teraHover", { type: i18next.t(`pokemonInfo:Type.${Type[this.lastTeraType]}`) }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -542,7 +542,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
|
|||||||
this.genderText.setPositionRelative(this.nameText, this.nameText.displayWidth, 0);
|
this.genderText.setPositionRelative(this.nameText, this.nameText.displayWidth, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const teraType = pokemon.getTeraType();
|
const teraType = pokemon.isTerastallized ? pokemon.getTeraType() : Type.UNKNOWN;
|
||||||
const teraTypeUpdated = this.lastTeraType !== teraType;
|
const teraTypeUpdated = this.lastTeraType !== teraType;
|
||||||
|
|
||||||
if (teraTypeUpdated) {
|
if (teraTypeUpdated) {
|
||||||
|
@ -8,6 +8,7 @@ import { getPokemonNameWithAffix } from "#app/messages";
|
|||||||
import { CommandPhase } from "#app/phases/command-phase";
|
import { CommandPhase } from "#app/phases/command-phase";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { TerastallizeAccessModifier } from "#app/modifier/modifier";
|
import { TerastallizeAccessModifier } from "#app/modifier/modifier";
|
||||||
|
import { Type } from "#app/enums/type";
|
||||||
|
|
||||||
export enum Command {
|
export enum Command {
|
||||||
FIGHT = 0,
|
FIGHT = 0,
|
||||||
@ -46,7 +47,7 @@ export default class CommandUiHandler extends UiHandler {
|
|||||||
|
|
||||||
this.teraButton = globalScene.add.sprite(-35, 15, "button_tera");
|
this.teraButton = globalScene.add.sprite(-35, 15, "button_tera");
|
||||||
this.teraButton.setName("terrastallize-button");
|
this.teraButton.setName("terrastallize-button");
|
||||||
this.teraButton.setScale(1.8);
|
this.teraButton.setScale(1.5);
|
||||||
this.teraButton.setFrame("fire");
|
this.teraButton.setFrame("fire");
|
||||||
this.commandsContainer.add(this.teraButton);
|
this.commandsContainer.add(this.teraButton);
|
||||||
|
|
||||||
@ -73,15 +74,13 @@ export default class CommandUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.canTera()) {
|
if (this.canTera()) {
|
||||||
this.teraButton.setFrame(globalScene.getField()[this.fieldIndex].getTeraType().toString().toLowerCase());
|
this.teraButton.setVisible(true);
|
||||||
} else {
|
this.teraButton.setFrame(Type[globalScene.getField()[this.fieldIndex].getTeraType()].toLowerCase());
|
||||||
this.teraButton.setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.canTera()) {
|
|
||||||
this.teraButton.setFrame(globalScene.getField()[this.fieldIndex].getTeraType().toString().toLowerCase());
|
|
||||||
} else {
|
} else {
|
||||||
this.teraButton.setVisible(false);
|
this.teraButton.setVisible(false);
|
||||||
|
if (this.cursor === Command.TERA) {
|
||||||
|
this.setCursor(Command.FIGHT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageHandler = this.getUi().getMessageHandler();
|
const messageHandler = this.getUi().getMessageHandler();
|
||||||
@ -131,9 +130,6 @@ export default class CommandUiHandler extends UiHandler {
|
|||||||
success = true;
|
success = true;
|
||||||
break;
|
break;
|
||||||
case Command.TERA:
|
case Command.TERA:
|
||||||
if ((globalScene.getCurrentPhase() as CommandPhase).checkFightOverride()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
ui.setMode(Mode.FIGHT, (globalScene.getCurrentPhase() as CommandPhase).getFieldIndex(), Command.TERA);
|
ui.setMode(Mode.FIGHT, (globalScene.getCurrentPhase() as CommandPhase).getFieldIndex(), Command.TERA);
|
||||||
success = true;
|
success = true;
|
||||||
break;
|
break;
|
||||||
@ -178,7 +174,10 @@ export default class CommandUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canTera(): boolean {
|
canTera(): boolean {
|
||||||
return !!globalScene.getModifiers(TerastallizeAccessModifier).length;
|
const hasTeraMod = !!globalScene.getModifiers(TerastallizeAccessModifier).length;
|
||||||
|
const currentTeras = globalScene.getPlayerParty().filter(p => p.isTerastallized).length;
|
||||||
|
const plannedTera = globalScene.currentBattle.preTurnCommands[0]?.command === Command.TERA;
|
||||||
|
return hasTeraMod && currentTeras < 1 && !plannedTera;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCursor(): integer {
|
getCursor(): integer {
|
||||||
@ -200,7 +199,12 @@ export default class CommandUiHandler extends UiHandler {
|
|||||||
this.commandsContainer.add(this.cursorObj);
|
this.commandsContainer.add(this.cursorObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cursorObj.setPosition(-5 + (cursor % 2 === 1 ? 56 : 0), 8 + (cursor >= 2 ? 16 : 0));
|
if (cursor === Command.TERA) {
|
||||||
|
this.cursorObj.setVisible(false);
|
||||||
|
} else {
|
||||||
|
this.cursorObj.setPosition(-5 + (cursor % 2 === 1 ? 56 : 0), 8 + (cursor >= 2 ? 16 : 0));
|
||||||
|
this.cursorObj.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
@ -420,17 +420,6 @@ export default class RunInfoUiHandler extends UiHandler {
|
|||||||
private parseTrainerDefeat(enemyContainer: Phaser.GameObjects.Container) {
|
private parseTrainerDefeat(enemyContainer: Phaser.GameObjects.Container) {
|
||||||
// Loads and adds trainer sprites to the UI
|
// Loads and adds trainer sprites to the UI
|
||||||
this.showTrainerSprites(enemyContainer);
|
this.showTrainerSprites(enemyContainer);
|
||||||
// Determining which Terastallize Modifier belongs to which Pokemon
|
|
||||||
// Creates a dictionary {PokemonId: TeraShardType}
|
|
||||||
const teraPokemon = {};
|
|
||||||
this.runInfo.enemyModifiers.forEach((m) => {
|
|
||||||
const modifier = m.toModifier(this.modifiersModule[m.className]);
|
|
||||||
if (modifier instanceof Modifier.TerastallizeModifier) {
|
|
||||||
const teraDetails = modifier?.getArgs();
|
|
||||||
const pkmnId = teraDetails[0];
|
|
||||||
teraPokemon[pkmnId] = teraDetails[1];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Creates the Pokemon icons + level information and adds it to enemyContainer
|
// Creates the Pokemon icons + level information and adds it to enemyContainer
|
||||||
// 2 Rows x 3 Columns
|
// 2 Rows x 3 Columns
|
||||||
@ -444,18 +433,6 @@ export default class RunInfoUiHandler extends UiHandler {
|
|||||||
enemyData["player"] = true;
|
enemyData["player"] = true;
|
||||||
const enemy = enemyData.toPokemon();
|
const enemy = enemyData.toPokemon();
|
||||||
const enemyIcon = globalScene.addPokemonIcon(enemy, 0, 0, 0, 0);
|
const enemyIcon = globalScene.addPokemonIcon(enemy, 0, 0, 0, 0);
|
||||||
// Applying Terastallizing Type tint to Pokemon icon
|
|
||||||
// If the Pokemon is a fusion, it has two sprites and so, the tint has to be applied to each icon separately
|
|
||||||
const enemySprite1 = enemyIcon.list[0] as Phaser.GameObjects.Sprite;
|
|
||||||
const enemySprite2 = (enemyIcon.list.length > 1) ? enemyIcon.list[1] as Phaser.GameObjects.Sprite : undefined;
|
|
||||||
if (teraPokemon[enemyData.id]) {
|
|
||||||
const teraTint = getTypeRgb(teraPokemon[enemyData.id]);
|
|
||||||
const teraColor = new Phaser.Display.Color(teraTint[0], teraTint[1], teraTint[2]);
|
|
||||||
enemySprite1.setTint(teraColor.color);
|
|
||||||
if (enemySprite2) {
|
|
||||||
enemySprite2.setTint(teraColor.color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enemyIcon.setPosition(39 * (e % 3) + 5, (35 * pokemonRowHeight));
|
enemyIcon.setPosition(39 * (e % 3) + 5, (35 * pokemonRowHeight));
|
||||||
const enemyLevel = addTextObject(43 * (e % 3), (27 * (pokemonRowHeight + 1)), `${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(enemy.level, 1000)}`, isBoss ? TextStyle.PARTY_RED : TextStyle.PARTY, { fontSize: "54px" });
|
const enemyLevel = addTextObject(43 * (e % 3), (27 * (pokemonRowHeight + 1)), `${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(enemy.level, 1000)}`, isBoss ? TextStyle.PARTY_RED : TextStyle.PARTY, { fontSize: "54px" });
|
||||||
enemyLevel.setShadow(0, 0, undefined);
|
enemyLevel.setShadow(0, 0, undefined);
|
||||||
|
@ -331,6 +331,7 @@ export default class SummaryUiHandler extends UiHandler {
|
|||||||
console.error(`Failed to play animation for ${spriteKey}`, err);
|
console.error(`Failed to play animation for ${spriteKey}`, err);
|
||||||
}
|
}
|
||||||
this.pokemonSprite.setPipelineData("teraColor", getTypeRgb(this.pokemon.getTeraType()));
|
this.pokemonSprite.setPipelineData("teraColor", getTypeRgb(this.pokemon.getTeraType()));
|
||||||
|
this.pokemonSprite.setPipelineData("isTerastallized", this.pokemon.isTerastallized);
|
||||||
this.pokemonSprite.setPipelineData("ignoreTimeTint", true);
|
this.pokemonSprite.setPipelineData("ignoreTimeTint", true);
|
||||||
this.pokemonSprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey());
|
this.pokemonSprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey());
|
||||||
this.pokemonSprite.setPipelineData("shiny", this.pokemon.shiny);
|
this.pokemonSprite.setPipelineData("shiny", this.pokemon.shiny);
|
||||||
|
Loading…
Reference in New Issue
Block a user