From 885fac7d18ee5969937d57d0cb09dd4ed23ec80e Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Tue, 28 Jan 2025 14:54:57 +1100 Subject: [PATCH] Commit old stashed changes --- public/images/ui/button_tera.json | 158 +++++++++++++++++++++++ public/images/ui/button_tera.png | Bin 0 -> 3603 bytes public/images/ui/legacy/button_tera.json | 158 +++++++++++++++++++++++ public/images/ui/legacy/button_tera.png | Bin 0 -> 3603 bytes src/battle.ts | 1 + src/data/ability.ts | 4 +- src/data/battler-tags.ts | 2 +- src/data/move.ts | 16 +-- src/field/pokemon.ts | 40 +++--- src/loading-scene.ts | 1 + src/phases/command-phase.ts | 2 + src/phases/tera-phase.ts | 34 +++++ src/system/pokemon-data.ts | 5 + src/ui/command-ui-handler.ts | 47 ++++++- src/ui/fight-ui-handler.ts | 4 +- src/ui/summary-ui-handler.ts | 2 +- 16 files changed, 439 insertions(+), 35 deletions(-) create mode 100644 public/images/ui/button_tera.json create mode 100644 public/images/ui/button_tera.png create mode 100644 public/images/ui/legacy/button_tera.json create mode 100644 public/images/ui/legacy/button_tera.png create mode 100644 src/phases/tera-phase.ts diff --git a/public/images/ui/button_tera.json b/public/images/ui/button_tera.json new file mode 100644 index 00000000000..7b64db66ae6 --- /dev/null +++ b/public/images/ui/button_tera.json @@ -0,0 +1,158 @@ +{ "frames": { + "unknown": { + "frame": { "x": 0, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "bug": { + "frame": { "x": 18, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "dark": { + "frame": { "x": 36, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "dragon": { + "frame": { "x": 54, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "electric": { + "frame": { "x": 72, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "fairy": { + "frame": { "x": 0, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "fighting": { + "frame": { "x": 18, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "fire": { + "frame": { "x": 36, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "flying": { + "frame": { "x": 54, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "ghost": { + "frame": { "x": 72, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "grass": { + "frame": { "x": 0, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "ground": { + "frame": { "x": 18, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "ice": { + "frame": { "x": 36, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "normal": { + "frame": { "x": 54, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "poison": { + "frame": { "x": 72, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "psychic": { + "frame": { "x": 0, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "rock": { + "frame": { "x": 18, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "steel": { + "frame": { "x": 36, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "water": { + "frame": { "x": 54, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "stellar": { + "frame": { "x": 72, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + } + }, + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-dev", + "image": "button_tera.png", + "format": "RGBA8888", + "size": { "w": 90, "h": 84 }, + "scale": "1", + "frameTags": [ + ], + "layers": [ + { "name": "Sprite Sheet", "opacity": 255, "blendMode": "normal" } + ], + "slices": [ + ] + } +} diff --git a/public/images/ui/button_tera.png b/public/images/ui/button_tera.png new file mode 100644 index 0000000000000000000000000000000000000000..a001020feb93e10941e9b29a8aeb85cc5bea3a77 GIT binary patch literal 3603 zcmds(`8(8q7sfv#h9X%qLeZ0iuS$ratiwndj5U#JWKXj1Tgeim?2RZiWQMVCLzeU% zWGrJR!&ovz_QZ(KGhNSr@to^=z3+3KU(PT0b?$e(DH6fUbD9SL0N$I1a1={zSy({W zS+7cHzcx$Qd{78ofY>X(1OP{JOmAE0vxXwT*|We|;HWeJsHy{3BqcAxWTed{&W1vv z)(U6BU<$xZz`>N?0j^-Jqh{hP3tYH&^~PNlDJMlW-#{r#C$&JYt6s{c+7N9I1v_7B z6C)iv2OnD_lOR_lI+Oqajn|}CrIaHLpg0ta7_70XBe3lW{6;B8AN8oY>XPgaPY6Ii z3-JOG_G>yp%6W1jg$VmjR7fxCd9-NhCn*ps))pr{P@@b|kAq~zPdMBBj0omS8}jo9 zO=E~ciuc;MJvbiF4@LmO(T-QK;>gHbX7S*7JXmpLdf14(HAOy{Lt?{D7vS!C8 z<+V{q*+t^MjZ*8gti%PQkQeU>#mChA4EfkT! z+DYoOVH#%o^DD3;8U$bdno9v^Gr)s)G%BI5yS}fhdA7Ce&lfyxIgk3iZfCjl03?F5 zEg+)_TqZHV=JcfT^33kkhUtRBc06vRynMXi*=A1p;@i^SP34;%*=@tco&+a;GFrjaw!QTZ5d5+*|809~3f!cDJJVhNF1L}H{jIx{ zVJ2-FWOnWBbb$+0aQ+(zPVEfM{2X0hqtL?ckusPlYN@10KjwhCS1qDCT2MEz#)|(OfDwfy?1Kr0fd8WXh-h;oN?va z=WZa1%>Z(&>;3)Z+IsxA{F>}pJnnY+;syJki&j6Zz7P$BWXzws5EKX=INAycudw<@ zL4y%K)8$ju7j7HAh%-6k{i|1X)JH9M%hm3!5c(a2*>(`sgwY_j(nM`Kkg=qOZ z-Cw`Dxj~5YIangiU^uJ9!epJWW1yXuufk8i~!oB09ZOiOF#CWftNJQYB^j@cabp@H*AC%4LQ|i z!JoAm+*NE)pGdPYo>#NdUVMPz3sKfc<0>(9bLi6)N{j`rNp?$N5 zve25Tvd(?W(!SYjTBM4W`w$5ar8l@)x|7>rz)|r_>R)*8vw4|YI>vtR5Sf>-8kTxY z=*v_8fQKG6wUmCS#Fya`jdo~MICaeCA5YbK+N#ly<+P-aKfeX680y?9F8g*>Nh!c* zeeK&s)6l56ot@n;@k&BmkM{?j56~*Z1|0O;#q@Lk+7w!33!(o-S)y)J_~UyO3!~t7 zk0bI`Ph;TDEJR+4o^uw;_n{~qr=F^MwwUC^MSa8K--&DYVMm$sHT8bZ=!8|r+9l-E zVXP&;hVStJ^gpAXj#d%XBpq6@#9+>MVcMIf^1_h{U8RL&iUH-ZBSEZ0Ndq%cVOyp2 zsj1S#e?sQ+ZR`k9OCX-oD`3}UWo@mhX6Pl2c>MV17_=?DFf%jL+6qD((uBc+W{$M& zO(a3uO894&KXAtIJ9Pg#(xgm|*?m-;o*sK5YEI_n+JNaE<0vK>9Uj4P?sY_KY*kfU z^6pWuxr`I zdCMNxyv4;a#SXgV&)&K|pJtp5slR^17#Xrp;5qON(ReqS1KBqJ5qI`aj_*ZoDkNg7 z$6+S({A=@hFLCdt$h?_X?PhS~rfi^H}pa{VQP$xkY)G&Y8x4B1{JjR4&G`qY|2cI%G| z_>rFkM>F>o&3vc1;U#N{lx?WQo+m2B*w4`H2+jaz5o;G!#B(gfY!I(!I|yqKZh>## zbN2V&N#;L@MW(%Ds>|le$9Efq*{4MYi)-x&@^v(?DxANH5ES1hsYv`{e+XjeyCxUz z;>{B(c6VKTQ37agls+m^*yxv$V#cLmIq6X%+*xc;JAaNBkuS(H+A)?68oP^7#}`Cj zEC#YH#=%0Dg>TqTr+^=+s+um(b8q*Lb>7^XlsA7K6KYbTw|^E>DE6AbLyJ%LKA9XBPly-m?|h^&HSYEfvt` z6Dsag+}Y}2pJih}HutSU&$1yo+j7sgei6EpXnHR8ilPBIKxA$9SW1{O(~cv;or9nE zk_gP7jp5Rm^Oo(o4__2lCwGi45J1k<D<`sZPS+6c-?@DSl=UaUtg zndZ|lLoJd^?`gS)Nd9s0Bzlx2?0a6eSE^eWm*8s10LQ>+J|yXdW8P8%`?6jUuD_TN&Q1P zom%*Qn}lcLVWxRAWZq6(rlsLg*mWcU0mdLzP=yHSYJ*kC&vt8LT_S5M|w~tPvuB z=)1y(@#oKRXW`5uuZ%Wi5w>~Z!VjdUX~5=JKbeA{9=SLPra8&K@x?YmET=!Gfr~U4 zVIOcBQ&#L((w_)xd_kf-o)^u5s%XqKaQQeDm4U%6<9osF8&6m(st5#kmpHmnE|p4+ z=Z=<-VJs}1xh`3ca)^ike=T!ZGmZ50+BfDpS}u%wiY)nImFi+S!Y$l%Asap)A~qgu zYt#2*0HTl7A>m@AgK87|diUKr&oEIcGO^_FH)j`;m4S$*0}jdYXYsOEDNiq@v}a|V z`wfcH*WONc*ytb4%VR5>mJCu#(k$A#(zy-zqW>}1)KZdxZ*$X+kxx=b7Tec40Hi~Dl62QTvblV@v;5o@wKn-5|% z<3X4x{e!cxLj40JCYJl);-4jo=-96b_j2R+6(g}TOaG|*j5XLUr^3mUGnVdVD`&nE z-FW*42A*R3n?|y0J#Vm2+qN7F-)(sOt@%qtQYZUZs%5k{o=?^oi9FOy%g6|}h~1uN z2$Hy3;Qodk_aZ+TYSLuX9hXNG0?+Z5Azt-_l%1ECcRz93CiOYYhDi z6>FndOKV*R3l)+}?$#lR_VK+}Sy?J0#_}eMI%scj)YN_3#<WAzXg Te`~-z^{?F2N5YA^_oM#{d>EMe literal 0 HcmV?d00001 diff --git a/public/images/ui/legacy/button_tera.json b/public/images/ui/legacy/button_tera.json new file mode 100644 index 00000000000..7b64db66ae6 --- /dev/null +++ b/public/images/ui/legacy/button_tera.json @@ -0,0 +1,158 @@ +{ "frames": { + "unknown": { + "frame": { "x": 0, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "bug": { + "frame": { "x": 18, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "dark": { + "frame": { "x": 36, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "dragon": { + "frame": { "x": 54, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "electric": { + "frame": { "x": 72, "y": 0, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "fairy": { + "frame": { "x": 0, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "fighting": { + "frame": { "x": 18, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "fire": { + "frame": { "x": 36, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "flying": { + "frame": { "x": 54, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "ghost": { + "frame": { "x": 72, "y": 21, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "grass": { + "frame": { "x": 0, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "ground": { + "frame": { "x": 18, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "ice": { + "frame": { "x": 36, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "normal": { + "frame": { "x": 54, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "poison": { + "frame": { "x": 72, "y": 42, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "psychic": { + "frame": { "x": 0, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "rock": { + "frame": { "x": 18, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "steel": { + "frame": { "x": 36, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "water": { + "frame": { "x": 54, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + }, + "stellar": { + "frame": { "x": 72, "y": 63, "w": 18, "h": 21 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 18, "h": 21 }, + "sourceSize": { "w": 20, "h": 23 } + } + }, + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-dev", + "image": "button_tera.png", + "format": "RGBA8888", + "size": { "w": 90, "h": 84 }, + "scale": "1", + "frameTags": [ + ], + "layers": [ + { "name": "Sprite Sheet", "opacity": 255, "blendMode": "normal" } + ], + "slices": [ + ] + } +} diff --git a/public/images/ui/legacy/button_tera.png b/public/images/ui/legacy/button_tera.png new file mode 100644 index 0000000000000000000000000000000000000000..a001020feb93e10941e9b29a8aeb85cc5bea3a77 GIT binary patch literal 3603 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 Te`~-z^{?F2N5YA^_oM#{d>EMe literal 0 HcmV?d00001 diff --git a/src/battle.ts b/src/battle.ts index 287a981f83d..c3dc4646951 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -68,6 +68,7 @@ export interface TurnCommand { targets?: BattlerIndex[]; skip?: boolean; args?: any[]; + preturnCommands?: Command[]; } export interface FaintLogEntry { diff --git a/src/data/ability.ts b/src/data/ability.ts index 5e5231176b5..a33f6b84854 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -1307,7 +1307,7 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { if ( - !pokemon.isTerastallized() && + !pokemon.isTerastallized && move.id !== Moves.STRUGGLE && /** * Skip moves that call other moves because these moves generate a following move that will trigger this ability attribute @@ -6194,7 +6194,7 @@ export function initAbilities() { .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) .attr(NoFusionAbilityAbAttr) - .condition((pokemon) => !pokemon.isTerastallized()), + .condition((pokemon) => !pokemon.isTerastallized), new Ability(Abilities.QUICK_DRAW, 8) .attr(BypassSpeedChanceAbAttr, 30), new Ability(Abilities.UNSEEN_FIST, 8) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 4c68de5abc5..37382de1c2c 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2493,7 +2493,7 @@ export class TarShotTag extends BattlerTag { * @returns whether the tag is applied */ override canAdd(pokemon: Pokemon): boolean { - return !pokemon.isTerastallized(); + return !pokemon.isTerastallized; } override onAdd(pokemon: Pokemon): void { diff --git a/src/data/move.ts b/src/data/move.ts index 06f3c85e9c4..74fc2ac8605 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4558,7 +4558,7 @@ export class TeraMoveCategoryAttr extends VariableMoveCategoryAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const category = (args[0] as Utils.NumberHolder); - if (user.isTerastallized() && user.getEffectiveStat(Stat.ATK, target, move) > user.getEffectiveStat(Stat.SPATK, target, move)) { + if (user.isTerastallized && user.getEffectiveStat(Stat.ATK, target, move) > user.getEffectiveStat(Stat.SPATK, target, move)) { category.value = MoveCategory.PHYSICAL; return true; } @@ -4585,7 +4585,7 @@ export class TeraBlastPowerAttr extends VariablePowerAttr { */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const power = args[0] as Utils.NumberHolder; - if (user.isTerastallized() && user.getTeraType() === Type.STELLAR) { + if (user.isTerastallized && user.getTeraType() === Type.STELLAR) { power.value = 100; return true; } @@ -4932,7 +4932,7 @@ export class TeraBlastTypeAttr extends VariableMoveTypeAttr { return false; } - if (user.isTerastallized()) { + if (user.isTerastallized) { moveType.value = user.getTeraType(); // changes move type to tera type return true; } @@ -6267,7 +6267,7 @@ export class RemoveTypeAttr extends MoveEffectAttr { return false; } - if (user.isTerastallized() && user.getTeraType() === this.removedType) { // active tera types cannot be removed + if (user.isTerastallized && user.getTeraType() === this.removedType) { // active tera types cannot be removed return false; } @@ -6447,7 +6447,7 @@ export class ChangeTypeAttr extends MoveEffectAttr { } getCondition(): MoveConditionFunc { - return (user, target, move) => !target.isTerastallized() && !target.hasAbility(Abilities.MULTITYPE) && !target.hasAbility(Abilities.RKS_SYSTEM) && !(target.getTypes().length === 1 && target.getTypes()[0] === this.type); + return (user, target, move) => !target.isTerastallized && !target.hasAbility(Abilities.MULTITYPE) && !target.hasAbility(Abilities.RKS_SYSTEM) && !(target.getTypes().length === 1 && target.getTypes()[0] === this.type); } } @@ -6470,7 +6470,7 @@ export class AddTypeAttr extends MoveEffectAttr { } getCondition(): MoveConditionFunc { - return (user, target, move) => !target.isTerastallized() && !target.getTypes().includes(this.type); + return (user, target, move) => !target.isTerastallized && !target.getTypes().includes(this.type); } } @@ -10887,7 +10887,7 @@ export function initMoves() { .attr(TeraMoveCategoryAttr) .attr(TeraBlastTypeAttr) .attr(TeraBlastPowerAttr) - .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, { condition: (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR) }) + .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, { condition: (user, target, move) => user.isTerastallized && user.isOfType(Type.STELLAR) }) .partial(), /** Does not ignore abilities that affect stats, relevant in determining the move's category {@see TeraMoveCategoryAttr} */ new SelfStatusMove(Moves.SILK_TRAP, Type.BUG, -1, 10, -1, 4, 9) .attr(ProtectAttr, BattlerTagType.SILK_TRAP) @@ -11084,7 +11084,7 @@ export function initMoves() { new AttackMove(Moves.TERA_STARSTORM, Type.NORMAL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9) .attr(TeraMoveCategoryAttr) .attr(TeraStarstormTypeAttr) - .attr(VariableTargetAttr, (user, target, move) => (user.hasFusionSpecies(Species.TERAPAGOS) || user.species.speciesId === Species.TERAPAGOS) && user.isTerastallized() ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER) + .attr(VariableTargetAttr, (user, target, move) => (user.hasFusionSpecies(Species.TERAPAGOS) || user.species.speciesId === Species.TERAPAGOS) && user.isTerastallized ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER) .partial(), /** Does not ignore abilities that affect stats, relevant in determining the move's category {@see TeraMoveCategoryAttr} */ new AttackMove(Moves.FICKLE_BEAM, Type.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9) .attr(PreMoveMessageAttr, doublePowerChanceMessageFunc) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 731d5c8fbe7..f31f5a8c3e7 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -131,6 +131,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public pokerus: boolean; public switchOutStatus: boolean; public evoCounter: integer; + public teraType: Type; + public isTerastallized: boolean; public fusionSpecies: PokemonSpecies | null; public fusionFormIndex: integer; @@ -239,6 +241,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.fusionCustomPokemonData = dataSource.fusionCustomPokemonData; this.usedTMs = dataSource.usedTMs ?? []; this.customPokemonData = new CustomPokemonData(dataSource.customPokemonData); + this.teraType = dataSource.teraType; + this.isTerastallized = dataSource.isTerastallized; } else { this.id = Utils.randSeedInt(4294967296); this.ivs = ivs || Utils.getIvsFromId(this.id); @@ -287,6 +291,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } this.luck = (this.shiny ? this.variant + 1 : 0) + (this.fusionShiny ? this.fusionVariant + 1 : 0); this.fusionLuck = this.luck; + + this.teraType = Utils.randSeedItem(this.getTypes(false, false, true)); + this.isTerastallized = false; } this.generateName(); @@ -1246,9 +1253,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public getTypes(includeTeraType = false, forDefend: boolean = false, ignoreOverride: boolean = false): Type[] { const types: Type[] = []; - if (includeTeraType) { + if (includeTeraType && this.isTerastallized) { const teraType = this.getTeraType(); - if (teraType !== Type.UNKNOWN) { + if (teraType !== Type.UNKNOWN && !(forDefend && teraType === Type.STELLAR)) { // Stellar tera uses its original types defensively types.push(teraType); if (forDefend) { return types; @@ -1557,21 +1564,19 @@ 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 */ - public getTeraType(): Type { - // I don't think this should be possible anymore, please report if you encounter this. --NightKev - if (globalScene === undefined) { - console.warn("Pokemon.getTeraType(): Global scene is not defined!"); - return Type.UNKNOWN; + getTeraType(): Type { + return this.teraType; + // this.scene can be undefined for a fainted mon in doubles + if (this.scene !== undefined) { + const teraModifier = globalScene.findModifier(m => m instanceof TerastallizeModifier + && m.pokemonId === this.id && !!m.getBattlesLeft(), this.isPlayer()) as TerastallizeModifier; + // return teraType + if (teraModifier) { + return teraModifier.teraType; + } } - const teraModifier = globalScene.findModifier(m => - m instanceof TerastallizeModifier - && m.pokemonId === this.id - && m.getBattlesLeft() > 0, this.isPlayer()) as TerastallizeModifier; - return teraModifier?.teraType ?? Type.UNKNOWN; - } - - public isTerastallized(): boolean { - return this.getTeraType() !== Type.UNKNOWN; + // if scene is undefined, or if teraModifier is considered false, then return unknown type + return Type.UNKNOWN; } public isGrounded(): boolean { @@ -1713,7 +1718,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ getAttackTypeEffectiveness(moveType: Type, source?: Pokemon, ignoreStrongWinds: boolean = false, simulated: boolean = true, move?: Move): TypeDamageMultiplier { if (moveType === Type.STELLAR) { - return this.isTerastallized() ? 2 : 1; + return this.isTerastallized ? 2 : 1; } const types = this.getTypes(true, true); const arena = globalScene.arena; @@ -3780,6 +3785,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { resetBattleData(): void { this.battleData = new PokemonBattleData(); + this.isTerastallized = true; } resetBattleSummonData(): void { diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 40b6417f9f2..2636fe065c5 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -103,6 +103,7 @@ export class LoadingScene extends SceneBase { this.loadImage("icon_tera", "ui"); this.loadImage("type_tera", "ui"); this.loadAtlas("type_bgs", "ui"); + this.loadAtlas("button_tera", "ui"); this.loadImage("dawn_icon_fg", "ui"); this.loadImage("dawn_icon_mg", "ui"); diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index e2bad953fc5..8892584acc5 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -119,6 +119,8 @@ export class CommandPhase extends FieldPhase { switch (command) { case Command.FIGHT: + case Command.TERA: + console.log("Fight From Command", command); let useStruggle = false; const turnMove: TurnMove | undefined = (args.length === 2 ? (args[1] as TurnMove) : undefined); if (cursor === -1 || diff --git a/src/phases/tera-phase.ts b/src/phases/tera-phase.ts new file mode 100644 index 00000000000..24af959142b --- /dev/null +++ b/src/phases/tera-phase.ts @@ -0,0 +1,34 @@ +import type Pokemon from "#app/field/pokemon"; +import { getPokemonNameWithAffix } from "#app/messages"; +import { BattlePhase } from "./battle-phase"; +import i18next from "i18next"; +import { globalScene } from "#app/global-scene"; +import { Type } from "#app/enums/type"; + +export class TeraPhase extends BattlePhase { + public pokemon: Pokemon; + + constructor(pokemon: Pokemon) { + super(); + + this.pokemon = pokemon; + } + + start() { + super.start(); + + console.log(this.pokemon.name, "terastallized to", Type[this.pokemon.teraType].toString()); // TODO: Improve log + + 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.end(); + } + + + end() { + this.pokemon.isTerastallized = true; + + super.end(); + } +} diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 92eca5c3e9f..45b7529a2ef 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -13,6 +13,7 @@ import type { Biome } from "#enums/biome"; import { Moves } from "#enums/moves"; import type { Species } from "#enums/species"; import { CustomPokemonData } from "#app/data/custom-pokemon-data"; +import type { Type } from "#app/enums/type"; export default class PokemonData { public id: integer; @@ -45,6 +46,8 @@ export default class PokemonData { public pokerus: boolean; public usedTMs: Moves[]; public evoCounter: integer; + public teraType: Type; + public isTerastallized: boolean; public fusionSpecies: Species; public fusionFormIndex: integer; @@ -103,6 +106,8 @@ export default class PokemonData { this.evoCounter = source.evoCounter ?? 0; } this.pokerus = !!source.pokerus; + this.teraType = (source.teraType || 0) as Type; + this.isTerastallized = source.isTerastallized || false; this.fusionSpecies = sourcePokemon ? sourcePokemon.fusionSpecies?.speciesId : source.fusionSpecies; this.fusionFormIndex = source.fusionFormIndex; diff --git a/src/ui/command-ui-handler.ts b/src/ui/command-ui-handler.ts index 32a3bb764a9..ee1dbcf581e 100644 --- a/src/ui/command-ui-handler.ts +++ b/src/ui/command-ui-handler.ts @@ -7,18 +7,22 @@ import { Button } from "#enums/buttons"; import { getPokemonNameWithAffix } from "#app/messages"; import { CommandPhase } from "#app/phases/command-phase"; import { globalScene } from "#app/global-scene"; +import { TerastallizeAccessModifier } from "#app/modifier/modifier"; export enum Command { FIGHT = 0, BALL, POKEMON, - RUN + RUN, + TERA } export default class CommandUiHandler extends UiHandler { private commandsContainer: Phaser.GameObjects.Container; private cursorObj: Phaser.GameObjects.Image | null; + private teraButton: Phaser.GameObjects.Sprite; + protected fieldIndex: integer = 0; protected cursor2: integer = 0; @@ -40,6 +44,12 @@ export default class CommandUiHandler extends UiHandler { this.commandsContainer.setVisible(false); ui.add(this.commandsContainer); + this.teraButton = globalScene.add.sprite(-35, 15, "button_tera"); + this.teraButton.setName("terrastallize-button"); + this.teraButton.setScale(1.8); + this.teraButton.setFrame("fire"); + this.commandsContainer.add(this.teraButton); + for (let c = 0; c < commands.length; c++) { const commandText = addTextObject(c % 2 === 0 ? 0 : 55.8, c < 2 ? 0 : 16, commands[c], TextStyle.WINDOW); commandText.setName(commands[c]); @@ -62,6 +72,18 @@ export default class CommandUiHandler extends UiHandler { commandPhase = globalScene.getStandbyPhase() as CommandPhase; } + if (this.canTera()) { + this.teraButton.setFrame(globalScene.getField()[this.fieldIndex].getTeraType().toString().toLowerCase()); + } else { + this.teraButton.setVisible(false); + } + + if (this.canTera()) { + this.teraButton.setFrame(globalScene.getField()[this.fieldIndex].getTeraType().toString().toLowerCase()); + } else { + this.teraButton.setVisible(false); + } + const messageHandler = this.getUi().getMessageHandler(); messageHandler.bg.setVisible(true); messageHandler.commandWindow.setVisible(true); @@ -108,6 +130,13 @@ export default class CommandUiHandler extends UiHandler { (globalScene.getCurrentPhase() as CommandPhase).handleCommand(Command.RUN, 0); success = true; break; + case Command.TERA: + if ((globalScene.getCurrentPhase() as CommandPhase).checkFightOverride()) { + return true; + } + ui.setMode(Mode.FIGHT, (globalScene.getCurrentPhase() as CommandPhase).getFieldIndex(), Command.TERA); + success = true; + break; } } else { (globalScene.getCurrentPhase() as CommandPhase).cancel(); @@ -115,23 +144,27 @@ export default class CommandUiHandler extends UiHandler { } else { switch (button) { case Button.UP: - if (cursor >= 2) { + if (cursor === Command.POKEMON || cursor === Command.RUN) { success = this.setCursor(cursor - 2); } break; case Button.DOWN: - if (cursor < 2) { + if (cursor === Command.FIGHT || cursor === Command.BALL) { success = this.setCursor(cursor + 2); } break; case Button.LEFT: - if (cursor % 2 === 1) { + if (cursor === Command.BALL || cursor === Command.RUN) { success = this.setCursor(cursor - 1); + } else if ((cursor === Command.FIGHT || cursor === Command.POKEMON) && this.canTera()) { + success = this.setCursor(Command.TERA); } break; case Button.RIGHT: - if (cursor % 2 === 0) { + if (cursor === Command.FIGHT || cursor === Command.POKEMON) { success = this.setCursor(cursor + 1); + } else if (cursor === Command.TERA) { + success = this.setCursor(Command.FIGHT); } break; } @@ -144,6 +177,10 @@ export default class CommandUiHandler extends UiHandler { return success; } + canTera(): boolean { + return !!globalScene.getModifiers(TerastallizeAccessModifier).length; + } + getCursor(): integer { return !this.fieldIndex ? this.cursor : this.cursor2; } diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index 220e5d817ef..3138edcce18 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -33,6 +33,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { private moveInfoOverlay : MoveInfoOverlay; protected fieldIndex: integer = 0; + protected fromCommand: integer = Command.FIGHT; protected cursor2: integer = 0; constructor() { @@ -114,6 +115,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { super.show(args); this.fieldIndex = args.length ? args[0] as integer : 0; + this.fromCommand = args.length > 1 ? args[1] as integer : Command.FIGHT; const messageHandler = this.getUi().getMessageHandler(); messageHandler.bg.setVisible(false); @@ -140,7 +142,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { if (button === Button.CANCEL || button === Button.ACTION) { if (button === Button.ACTION) { - if ((globalScene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, cursor, false)) { + if ((globalScene.getCurrentPhase() as CommandPhase).handleCommand(this.fromCommand, cursor, false)) { success = true; } else { ui.playError(); diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 3fe6a372737..7df1dab1d6e 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -775,7 +775,7 @@ export default class SummaryUiHandler extends UiHandler { if (types.length > 1) { profileContainer.add(getTypeIcon(1, types[1])); } - if (this.pokemon?.isTerastallized()) { + if (this.pokemon?.isTerastallized) { profileContainer.add(getTypeIcon(types.length, this.pokemon.getTeraType(), true)); }