From a9f8adfa392ac26b2ecabab9dc750b58ff19e6bf Mon Sep 17 00:00:00 2001 From: Adam Tran Date: Fri, 29 Jan 2021 11:10:36 -0500 Subject: [PATCH 001/770] Preact Client: Ladder (#1709) --- .eslintignore | 2 + .gitignore | 2 + preactalpha.template.html | 2 + src/client-main.ts | 2 +- src/panel-ladder.tsx | 277 ++++++++++++++++++++++++++++++++++++++ src/panel-mainmenu.tsx | 7 + src/panel-page.tsx | 78 +++++++++++ src/panel-topbar.tsx | 1 + src/panels.tsx | 4 + testclient-beta.html | 2 + 10 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 src/panel-ladder.tsx create mode 100644 src/panel-page.tsx diff --git a/.eslintignore b/.eslintignore index ae1754409a..2c5bf276c6 100644 --- a/.eslintignore +++ b/.eslintignore @@ -29,3 +29,5 @@ node_modules/ /js/panel-teambuilder-team.js /js/panel-teamdropdown.js /js/panel-battle.js +/js/panel-ladder.js +/js/panel-page.js diff --git a/.gitignore b/.gitignore index 961f550364..f8be3a1c5b 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,8 @@ package-lock.json /js/panel-teamdropdown.js /js/panel-battle.js /js/replay-embed.js +/js/panel-ladder.js +/js/panel-page.js /js/*.js.map /replays/caches/ diff --git a/preactalpha.template.html b/preactalpha.template.html index b279cde22b..2f128fee4c 100644 --- a/preactalpha.template.html +++ b/preactalpha.template.html @@ -92,6 +92,8 @@

+ ; + } + return null; + }; + const RenderFormat = () => { + if (loading || !BattleFormats) { + return

Loading...

; + } else if (error !== undefined) { + return

Error: {error}

; + } else if (BattleFormats[format] === undefined) { + return

Format {format} not found.

; + } else if (ladderData === undefined) { + return null; + } + return ( + <> +

+ + +

+ + {ladderData} + + ); + }; + return ( +
+

+ +

+ +
+ ); +} + +class LadderPanel extends PSRoomPanel { + componentDidMount() { + const { room } = this.props; + // Request ladder data either on mount or after BattleFormats are loaded + if (BattleFormats && room.format !== undefined) room.requestLadderData(); + this.subscriptions.push( + room.subscribe((response: any) => { + if (response) { + const [format, ladderData] = response; + if (room.format === format) { + if (!ladderData) { + room.setError(new Error('No data returned from server.')); + } else { + room.setLadderData(ladderData); + } + } + } + this.forceUpdate(); + }) + ); + this.subscriptions.push( + PS.teams.subscribe(() => { + if (room.format !== undefined) room.requestLadderData(); + this.forceUpdate(); + }) + ); + } + static Notice = (props: { notice: string | undefined }) => { + const { notice } = props; + if (notice) { + return ( +

+ {notice} +

+ ); + } + return null; + }; + static BattleFormatList = () => { + if (!BattleFormats) { + return

Loading...

; + } + let currentSection: string = ""; + let sections: JSX.Element[] = []; + let formats: JSX.Element[] = []; + for (const [key, format] of Object.entries(BattleFormats)) { + if (!format.rated || !format.searchShow) continue; + if (format.section !== currentSection) { + if (formats.length > 0) { + sections.push( + +

{currentSection}

+
    + {formats} +
+
+ ); + formats = []; + } + currentSection = format.section; + } + formats.push( +
  • + +
  • + ); + } + return <>{sections}; + }; + static ShowFormatList = (props: { room: LadderRoom }) => { + const { room } = props; + return ( + <> +

    + See a user's ranking with{" "} + + User lookup + +

    + +

    + (btw if you couldn't tell the ladder screens aren't done yet; + they'll look nicer than this once I'm done.) +

    +

    + +

    + + + ); + }; + render() { + const { room } = this.props; + return ( + +
    + {room.format === undefined && ( + + )} + {room.format !== undefined && } +
    +
    + ); + } +} + +PS.roomTypes['ladder'] = { + Model: LadderRoom, + Component: LadderPanel, +}; +PS.updateRoomTypes(); diff --git a/src/panel-mainmenu.tsx b/src/panel-mainmenu.tsx index 237950ba55..593bc5fe52 100644 --- a/src/panel-mainmenu.tsx +++ b/src/panel-mainmenu.tsx @@ -257,6 +257,13 @@ class MainMenuRoom extends PSRoom { battlesRoom.battles = battles; battlesRoom.update(null); } + break; + case 'laddertop': + const ladderRoomEntries = Object.entries(PS.rooms).filter(entry => entry[0].startsWith('ladder')); + for (const [, ladderRoom] of ladderRoomEntries) { + (ladderRoom as LadderRoom).update(response); + } + break; } } } diff --git a/src/panel-page.tsx b/src/panel-page.tsx new file mode 100644 index 0000000000..b00bb560b5 --- /dev/null +++ b/src/panel-page.tsx @@ -0,0 +1,78 @@ +/** + * Page Panel + * + * Panel for static content and server-rendered HTML. + * + * @author Adam Tran + * @license MIT + */ + +class PageRoom extends PSRoom { + readonly classType: string = 'page'; + readonly page?: string = this.id.split("-")[1]; + readonly canConnect = true; +} + +function PageNotFound() { + // Future development: server-rendered HTML panels + return

    Page not found

    ; +} + +function PagerLadderHelp(props: { room: PageRoom }) { + const { room } = props; + return ( +
    +

    + +

    +

    How the ladder works

    +

    Our ladder displays three ratings: Elo, GXE, and Glicko-1.

    +

    + Elo is the main ladder rating. It's a pretty + normal ladder rating: goes up when you win and down when you + lose. +

    +

    + GXE (Glicko X-Act Estimate) is an estimate of + your win chance against an average ladder player. +

    +

    + Glicko-1 is a different rating system. It has + rating and deviation values. +

    +

    + Note that win/loss should not be used to estimate skill, since + who you play against is much more important than how many times + you win or lose. Our other stats like Elo and GXE are much better + for estimating skill. +

    +
    + ); +} + +class PagePanel extends PSRoomPanel { + render() { + const { room } = this.props; + const RenderPage = () => { + switch (room.page) { + case 'ladderhelp': + return ; + default: + return ; + } + }; + return ( + + + + ); + } +} + +PS.roomTypes['html'] = { + Model: PageRoom, + Component: PagePanel, +}; +PS.updateRoomTypes(); diff --git a/src/panel-topbar.tsx b/src/panel-topbar.tsx index 62fe6f6edd..dfb72f2747 100644 --- a/src/panel-topbar.tsx +++ b/src/panel-topbar.tsx @@ -28,6 +28,7 @@ class PSHeader extends preact.Component<{style: {}}> { icon = ; break; case 'ladder': + case 'ladderformat': icon = ; break; case 'battles': diff --git a/src/panels.tsx b/src/panels.tsx index 45badba6c2..45c2429f4a 100644 --- a/src/panels.tsx +++ b/src/panels.tsx @@ -478,3 +478,7 @@ class PSMain extends preact.Component { } type PanelPosition = {top?: number, bottom?: number, left?: number, right?: number} | null; + +function SanitizedHTML(props: {children: string}) { + return
    ; +} diff --git a/testclient-beta.html b/testclient-beta.html index 4ca71217f9..ad02dce6a8 100644 --- a/testclient-beta.html +++ b/testclient-beta.html @@ -110,6 +110,8 @@

    '; } else { - buf += '

    '; + buf += '

    '; buf += '

    '; } From ba2b18d012291a818566021fd287a5266cf1442c Mon Sep 17 00:00:00 2001 From: Adam Tran Date: Fri, 29 Jan 2021 21:53:35 -0500 Subject: [PATCH 003/770] Preact: Page Panel (#1716) --- src/panel-page.tsx | 91 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 16 deletions(-) diff --git a/src/panel-page.tsx b/src/panel-page.tsx index b00bb560b5..a8ba8a0c1d 100644 --- a/src/panel-page.tsx +++ b/src/panel-page.tsx @@ -8,18 +8,34 @@ */ class PageRoom extends PSRoom { - readonly classType: string = 'page'; + readonly classType: string = 'html'; readonly page?: string = this.id.split("-")[1]; readonly canConnect = true; -} -function PageNotFound() { - // Future development: server-rendered HTML panels - return

    Page not found

    ; + loading: boolean = true; + htmlData?: string; + + setHTMLData = (htmlData?: string) => { + this.loading = false; + this.htmlData = htmlData; + this.update(null); + }; + + constructor(options: RoomOptions) { + super(options); + this.connect(); + } + connect() { + if (!this.connected) { + PS.send(`|/join ${this.id}`); + this.connected = true; + this.connectWhenLoggedIn = false; + } + } } -function PagerLadderHelp(props: { room: PageRoom }) { - const { room } = props; +function PageLadderHelp(props: {room: PageRoom}) { + const {room} = props; return (

    @@ -53,19 +69,62 @@ function PagerLadderHelp(props: { room: PageRoom }) { } class PagePanel extends PSRoomPanel { + clientRooms: { [key: string]: JSX.Element } = { 'ladderhelp': }; + + /** + * @return true to prevent line from being sent to server + */ + receiveLine(args: Args) { + const {room} = this.props; + switch (args[0]) { + case 'title': + room.title = args[1]; + PS.update(); + return true; + case 'tempnotify': { + const [, id, title, body] = args; + room.notify({title, body, id}); + return true; + } + case 'tempnotifyoff': { + const [, id] = args; + room.dismissNotification(id); + return true; + } + case 'selectorhtml': + const pageHTMLContainer = this.base!.querySelector('.page-html-container'); + const selectedElement = pageHTMLContainer?.querySelector(args[1]); + if (!selectedElement) return; + selectedElement.innerHTML = BattleLog.sanitizeHTML(args.slice(2).join('|')); + room.isSubtleNotifying = true; + return true; + case 'noinit': + if (args[1] === 'namerequired') { + room.setHTMLData(args[2]); + } + return true; + case 'pagehtml': + room.setHTMLData(args[1]); + return true; + } + } render() { - const { room } = this.props; - const RenderPage = () => { - switch (room.page) { - case 'ladderhelp': - return ; - default: - return ; + const {room} = this.props; + let renderPage; + if (room.page !== undefined && this.clientRooms[room.page]) { + renderPage = this.clientRooms[room.page]; + } else { + if (room.loading) { + renderPage =

    Loading...

    ; + } else { + renderPage =
    + {room.htmlData || ''} +
    ; } - }; + } return ( - + {renderPage} ); } From c621da6a01db60d3bc15dfb12ed46e0f4080e87a Mon Sep 17 00:00:00 2001 From: urkerab Date: Sun, 31 Jan 2021 06:13:23 +0000 Subject: [PATCH 004/770] Explicitly mark more non-submit buttons with their type (#1718) --- js/client-battle.js | 4 ++-- js/client-mainmenu.js | 4 ++-- js/client-teambuilder.js | 2 +- js/client-topbar.js | 14 +++++++------- js/client.js | 10 +++++----- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/js/client-battle.js b/js/client-battle.js index 7873e90a94..c1a96640db 100644 --- a/js/client-battle.js +++ b/js/client-battle.js @@ -1381,9 +1381,9 @@ buf += '

    '; } if (this.gameType === 'battle' && this.room.battle && !this.room.battle.rated) { - buf += ' '; + buf += ' '; } - buf += '

    '; + buf += '

    '; this.$el.html(buf); }, replacePlayer: function (data) { diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index 147a87053b..9ab37055ed 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -710,7 +710,7 @@ buf += '

    ' + self.renderFormats(format, true) + '

    '; buf += '

    ' + self.renderTeams(format) + '

    '; buf += '

    '; - buf += '

    '; + buf += '

    '; $challenge.html(buf); if (format.substr(0, 4) === 'gen5') atLeastOneGen5 = true; } @@ -810,7 +810,7 @@ buf += '

    ' + this.renderFormats(format) + '

    '; buf += '

    ' + this.renderTeams(format) + '

    '; buf += '

    '; - buf += '

    '; + buf += '

    '; $challenge.html(buf); }, acceptChallenge: function (i, target) { diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 3d8d9cd809..ae774abec7 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -3257,7 +3257,7 @@ this.room = data.room; this.folder = data.folder; var buf = '

    Remove "' + data.folder.slice(0, -1) + '"?

    '; - buf += '

    '; + buf += '

    '; this.$el.html(buf); }, submit: function (data) { diff --git a/js/client-topbar.js b/js/client-topbar.js index e8477ac0d4..b7535848d7 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -856,7 +856,7 @@ if (noRenameGames) { buf += '

    You can\'t change name in the middle of these games:

    '; buf += '
      ' + noRenameGames + '
    '; - buf += '

    '; + buf += '

    '; buf += '

    '; buf += ''; this.$el.html(buf); @@ -870,7 +870,7 @@ if (name) { buf += '

    (Others will be able to see your name change. To change name privately, use "Log out")

    '; } - buf += '

    '; + buf += '

    '; buf += ''; this.$el.html(buf); @@ -913,7 +913,7 @@ buf += '

    '; buf += '

    '; buf += '

    '; - buf += '

    '; + buf += '

    '; this.$el.html(buf); }, submit: function (data) { @@ -951,7 +951,7 @@ buf += '

    '; buf += '

    '; buf += '

    '; - buf += '

    '; + buf += '

    '; this.$el.html(buf); }, submit: function (data) { @@ -1023,13 +1023,13 @@ buf += '
    [loading Google log-in button]
    '; buf += '

    '; } else { - buf += '

    '; - buf += '

    '; + buf += '

    '; + buf += '

    '; } buf += '

    or

    '; buf += '

    If this is someone else\'s account:

    '; - buf += '

    '; + buf += '

    '; buf += ''; this.$el.html(buf); diff --git a/js/client.js b/js/client.js index ec5de0b08c..24f1e35b3e 100644 --- a/js/client.js +++ b/js/client.js @@ -2353,7 +2353,7 @@ function toId() { }, initialize: function (data) { if (!this.type) this.type = 'semimodal'; - this.$el.html('

    ' + (data.htmlMessage || BattleLog.parseMessage(data.message)) + '

    ' + (data.buttons || '') + '

    ').css('max-width', data.maxWidth || 480); + this.$el.html('

    ' + (data.htmlMessage || BattleLog.parseMessage(data.message)) + '

    ' + (data.buttons || '') + '

    ').css('max-width', data.maxWidth || 480); }, dispatchClickButton: function (e) { @@ -2417,7 +2417,7 @@ function toId() { var buf = '
    '; buf += '

    '; - buf += '

    '; + buf += '

    '; buf += '
    '; this.$el.html(buf); @@ -2701,10 +2701,10 @@ function toId() { } } else if (data.message && data.message !== true) { buf += '

    ' + data.message + '

    '; - buf += '

    '; + buf += '

    '; } else { buf += '

    You have been disconnected – possibly because the server was restarted.

    '; - buf += '

    '; + buf += '

    '; } buf += ''; @@ -2730,7 +2730,7 @@ function toId() { buf += '

    Please copy all the text from the box above and paste it in the box below.

    '; buf += '

    (You should probably set up config/testclient-key.js so you don\'t have to do this every time.)

    '; buf += '

    '; - buf += '

    '; + buf += '

    '; buf += ''; this.$el.html(buf).css('min-width', 500); }, From f94d89887e35e84b5206265eb53d03820f89dce9 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Fri, 29 Jan 2021 18:59:01 -0500 Subject: [PATCH 005/770] Improve design of "Show password" button --- js/client-topbar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-topbar.js b/js/client-topbar.js index b7535848d7..8edd741f34 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -1023,7 +1023,7 @@ buf += '
    [loading Google log-in button]
    '; buf += '

    '; } else { - buf += '

    '; + buf += '

    '; buf += '

    '; } From e9bc53d899694c342ae4f1273be4016a4dfdd37f Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sun, 31 Jan 2021 01:23:53 -0500 Subject: [PATCH 006/770] Fix crash in sorting users Reported here: https://www.smogon.com/forums/threads/make-command-to-undo-ioo.3677346/#post-8736801 --- js/client-chat.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js/client-chat.js b/js/client-chat.js index 730451a12c..d1f0e3a1b1 100644 --- a/js/client-chat.js +++ b/js/client-chat.js @@ -1892,20 +1892,20 @@ comparator: function (a, b) { if (a === b) return 0; - var aUser = this.room.users[a]; - var bUser = this.room.users[b]; + var aUser = this.room.users[a] || {group: Config.defaultGroup, away: false}; + var bUser = this.room.users[b] || {group: Config.defaultGroup, away: false}; var aRank = ( - Config.groups[aUser ? aUser.group : Config.defaultGroup || ' '] || + Config.groups[aUser.group || ' '] || {order: (Config.defaultOrder || 10006.5)} ).order; var bRank = ( - Config.groups[bUser ? bUser.group : Config.defaultGroup || ' '] || + Config.groups[bUser.group || ' '] || {order: (Config.defaultOrder || 10006.5)} ).order; if (aRank !== bRank) return aRank - bRank; - if (aUser.away !== bUser.away) return aUser.away - bUser.away; + if ((aUser.away ? 1 : 0) !== (bUser.away ? 1 : 0)) return (aUser.away ? 1 : 0) - (bUser.away ? 1 : 0); return (a > b ? 1 : -1); }, getNoNamedUsersOnline: function () { From b3239205fc8c08863b8f35816c24208a2900cd90 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Sun, 31 Jan 2021 02:36:56 -0600 Subject: [PATCH 007/770] Fix broadcasting /help (#1715) --- js/client-chat.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/client-chat.js b/js/client-chat.js index d1f0e3a1b1..9a32a9036d 100644 --- a/js/client-chat.js +++ b/js/client-chat.js @@ -1048,7 +1048,6 @@ // documentation of client commands case 'help': case 'h': - if (this.checkBroadcast(cmd, text)) return false; switch (toID(target)) { case 'chal': case 'chall': From 868244d49fac35e558e1511a0c53bf8f841fb687 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Mon, 1 Feb 2021 15:18:38 -0600 Subject: [PATCH 008/770] Improve banning servers (#1719) --- js/client.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/js/client.js b/js/client.js index 24f1e35b3e..713b30f394 100644 --- a/js/client.js +++ b/js/client.js @@ -709,7 +709,17 @@ function toId() { connect: function () { if (this.down) return; - if (Config.server.banned || (Config.bannedHosts && Config.bannedHosts.indexOf(Config.server.host) >= 0)) { + if (Config.bannedHosts) { + for (var i = 0; i < Config.bannedHosts.length; i++) { + var host = Config.bannedHosts[i]; + if (typeof host === 'string' ? Config.server.host === host : host.test(Config.server.host)) { + Config.server.banned = true; + break; + } + } + } + + if (Config.server.banned) { this.addPopupMessage("This server has been deleted for breaking US laws, impersonating PS global staff, or other major rulebreaking."); return; } From aa82e72e9ac6885990b7b355dceba389e619d120 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Mon, 1 Feb 2021 23:40:20 -0800 Subject: [PATCH 009/770] Partial drag/drop panel tab rearranging (#1641) Not full support, but basic rearranging is now possible! Supported: - Rearranging the topbar - Dragging PMs from the Main Menu to the topbar Not supported: - Dragging things from the topbar to the Main Menu --- build-tools/build-indexes | 8 +-- src/client-main.ts | 11 ++++ src/panel-mainmenu.tsx | 6 +- src/panel-topbar.tsx | 123 +++++++++++++++++++++++++++++++++++++- src/panels.tsx | 57 ++++++++++-------- testclient-beta.html | 24 ++++++++ 6 files changed, 196 insertions(+), 33 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 6af02d26ac..2f1a7f13da 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -26,10 +26,10 @@ Dex.includeData(); console.log("DONE"); function es3stringify(obj) { - let buf = JSON.stringify(obj); - buf = buf.replace(/\"([A-Za-z][A-Za-z0-9]*)\"\:/g, '$1:'); - buf = buf.replace(/return\:/g, '"return":').replace(/new\:/g, '"new":').replace(/delete\:/g, '"delete":'); - return buf; + const buf = JSON.stringify(obj); + return buf.replace(/\"([A-Za-z][A-Za-z0-9]*)\"\:/g, (fullMatch, key) => ( + ['return', 'new', 'delete'].includes(key) ? fullMatch : `${key}:` + )); } function requireNoCache(pathSpec) { diff --git a/src/client-main.ts b/src/client-main.ts index 1dea48551f..9b0c08939f 100644 --- a/src/client-main.ts +++ b/src/client-main.ts @@ -636,6 +636,17 @@ const PS = new class extends PSModel { leftRoomWidth = 0; mainmenu: MainMenuRoom = null!; + /** + * The drag-and-drop API is incredibly dumb and doesn't let us know + * what's being dragged until the `drop` event, so we track it here. + * + * Note that `PS.dragging` will be null if the drag was initiated + * outside PS (e.g. dragging a team from File Explorer to PS), and + * for security reasons it's impossible to know what they are until + * they're dropped. + */ + dragging: {type: 'room', roomid: RoomID} | null = null; + /** Tracks whether or not to display the "Use arrow keys" hint */ arrowKeysUsed = false; diff --git a/src/panel-mainmenu.tsx b/src/panel-mainmenu.tsx index 593bc5fe52..99e0968190 100644 --- a/src/panel-mainmenu.tsx +++ b/src/panel-mainmenu.tsx @@ -283,6 +283,10 @@ class MainMenuPanel extends PSRoomPanel { submit = (e: Event) => { alert('todo: implement'); }; + handleDragStart = (e: DragEvent) => { + const roomid = (e.currentTarget as HTMLElement).getAttribute('data-roomid') as RoomID; + PS.dragging = {type: 'room', roomid}; + }; renderMiniRoom(room: PSRoom) { const roomType = PS.roomTypes[room.type]; const Panel = roomType ? roomType.Component : PSRoomPanel; @@ -293,7 +297,7 @@ class MainMenuPanel extends PSRoomPanel { const room = PS.rooms[roomid]!; return
    -

    +

    {room.title} diff --git a/src/panel-topbar.tsx b/src/panel-topbar.tsx index dfb72f2747..8b92152b85 100644 --- a/src/panel-topbar.tsx +++ b/src/panel-topbar.tsx @@ -3,13 +3,122 @@ * * Topbar view - handles the topbar and some generic popups. * - * Also sets up global event listeners. + * Also handles global drag-and-drop support. * * @author Guangcong Luo * @license AGPLv3 */ +window.addEventListener('drop', e => { + console.log('drop ' + e.dataTransfer!.dropEffect); + const target = e.target as HTMLElement; + if (/^text/.test((target as HTMLInputElement).type)) { + PS.dragging = null; + return; // Ignore text fields + } + + // The default team drop action for Firefox is to open the team as a + // URL, which needs to be prevented. + // The default file drop action for most browsers is to open the file + // in the tab, which is generally undesirable anyway. + e.preventDefault(); + PS.dragging = null; +}); +window.addEventListener('dragend', e => { + e.preventDefault(); + PS.dragging = null; +}); +window.addEventListener('dragover', e => { + // this prevents the bounce-back animation + e.preventDefault(); +}); + class PSHeader extends preact.Component<{style: {}}> { + handleDragEnter = (e: DragEvent) => { + console.log('dragenter ' + e.dataTransfer!.dropEffect); + e.preventDefault(); + if (!PS.dragging) return; // TODO: handle dragging other things onto roomtabs + /** the element being passed over */ + const target = e.currentTarget as HTMLAnchorElement; + + const draggingRoom = PS.dragging.roomid; + if (draggingRoom === null) return; + + const draggedOverRoom = PS.router.extractRoomID(target.href); + if (draggedOverRoom === null) return; // should never happen + if (draggingRoom === draggedOverRoom) return; + + const leftIndex = PS.leftRoomList.indexOf(draggedOverRoom); + if (leftIndex >= 0) { + this.dragOnto(draggingRoom, 'leftRoomList', leftIndex); + } else { + const rightIndex = PS.rightRoomList.indexOf(draggedOverRoom); + if (rightIndex >= 0) { + this.dragOnto(draggingRoom, 'rightRoomList', rightIndex); + } else { + return; + } + } + + // dropEffect !== 'none' prevents bounce-back animation in + // Chrome/Safari/Opera + // if (e.dataTransfer) e.dataTransfer.dropEffect = 'move'; + }; + handleDragStart = (e: DragEvent) => { + const roomid = PS.router.extractRoomID((e.currentTarget as HTMLAnchorElement).href); + if (!roomid) return; // should never happen + + PS.dragging = {type: 'room', roomid}; + }; + dragOnto(fromRoom: RoomID, toRoomList: 'leftRoomList' | 'rightRoomList' | 'miniRoomList', toIndex: number) { + // one day you will be able to rearrange mainmenu and rooms, but not today + if (fromRoom === '' || fromRoom === 'rooms') return; + + if (fromRoom === PS[toRoomList][toIndex]) return; + if (fromRoom === '' && toRoomList === 'miniRoomList') return; + + const roomLists = ['leftRoomList', 'rightRoomList', 'miniRoomList'] as const; + let fromRoomList; + let fromIndex = -1; + for (const roomList of roomLists) { + fromIndex = PS[roomList].indexOf(fromRoom); + if (fromIndex >= 0) { + fromRoomList = roomList; + break; + } + } + if (!fromRoomList) return; // shouldn't happen + + if (toRoomList === 'leftRoomList' && toIndex === 0) toIndex = 1; // Home is always leftmost + if (toRoomList === 'rightRoomList' && toIndex === PS.rightRoomList.length - 1) toIndex--; // Rooms is always rightmost + + PS[fromRoomList].splice(fromIndex, 1); + // if dragging within the same roomlist and toIndex > fromIndex, + // toIndex is offset by 1 now. Fortunately for us, we want to + // drag to the right of this tab in that case, so the -1 +1 + // cancel out + PS[toRoomList].splice(toIndex, 0, fromRoom); + + const room = PS.rooms[fromRoom]!; + switch (toRoomList) { + case 'leftRoomList': room.location = 'left'; break; + case 'rightRoomList': room.location = 'right'; break; + case 'miniRoomList': room.location = 'mini-window'; break; + } + if (fromRoomList !== toRoomList) { + if (fromRoom === PS.leftRoom.id) { + PS.leftRoom = PS.mainmenu; + } else if (PS.rightRoom && fromRoom === PS.rightRoom.id) { + PS.rightRoom = PS.rooms['rooms']!; + } + if (toRoomList === 'rightRoomList') { + PS.rightRoom = room; + } else if (toRoomList === 'leftRoomList') { + PS.leftRoom = room; + } + } + PS.update(); + } renderRoomTab(id: RoomID) { const room = PS.rooms[id]!; const closable = (id === '' || id === 'rooms' ? '' : ' closable'); @@ -82,7 +191,15 @@ class PSHeader extends preact.Component<{style: {}}> { ; } - return
  • {icon} {title}{closeButton}
  • ; + return
  • + + {icon} {title} + + {closeButton} +
  • ; } render() { const userColor = window.BattleLog && {color: BattleLog.usernameColor(PS.user.userid)}; @@ -97,7 +214,7 @@ class PSHeader extends preact.Component<{style: {}}> {
      - {this.renderRoomTab('' as RoomID)} + {this.renderRoomTab(PS.leftRoomList[0])}
      {PS.leftRoomList.slice(1).map(roomid => this.renderRoomTab(roomid))} diff --git a/src/panels.tsx b/src/panels.tsx index 45c2429f4a..ca2d06aab5 100644 --- a/src/panels.tsx +++ b/src/panels.tsx @@ -3,7 +3,7 @@ * * Main view - sets up the frame, and the generic panels. * - * Also sets up global event listeners. + * Also sets up most global event listeners. * * @author Guangcong Luo * @license AGPLv3 @@ -20,6 +20,34 @@ class PSRouter { this.subscribeHash(); } } + extractRoomID(url: string) { + if (url.startsWith(document.location.origin)) { + url = url.slice(document.location.origin.length); + } else { + if (url.startsWith('http://')) { + url = url.slice(7); + } else if (url.startsWith('https://')) { + url = url.slice(8); + } + if (url.startsWith(document.location.host)) { + url = url.slice(document.location.host.length); + } else if (PS.server.id === 'showdown' && url.startsWith('play.pokemonshowdown.com')) { + url = url.slice(24); + } else if (PS.server.id === 'showdown' && url.startsWith('psim.us')) { + url = url.slice(7); + } else if (url.startsWith('replay.pokemonshowdown.com')) { + url = url.slice(26).replace('/', '/battle-'); + } + } + if (url.startsWith('/')) url = url.slice(1); + + if (!/^[a-z0-9-]*$/.test(url)) return null; + + const redirects = /^(appeals?|rooms?suggestions?|suggestions?|adminrequests?|bugs?|bugreports?|rules?|faq|credits?|privacy|contact|dex|insecure)$/; + if (redirects.test(url)) return null; + + return url as RoomID; + } subscribeHash() { if (location.hash) { const currentRoomid = location.hash.slice(1); @@ -196,7 +224,9 @@ class PSMain extends preact.Component { return; } if (elem.tagName === 'A' || elem.getAttribute('data-href')) { - const roomid = this.roomidFromLink(elem as HTMLAnchorElement); + const href = elem.getAttribute('data-href') || (elem as HTMLAnchorElement).href; + const roomid = PS.router.extractRoomID(href); + if (roomid !== null) { PS.addRoom({ id: roomid, @@ -294,29 +324,6 @@ class PSMain extends preact.Component { } return false; } - roomidFromLink(elem: HTMLAnchorElement) { - let href = elem.getAttribute('data-href'); - if (href) { - // yes that's what we needed - } else if (PS.server.id === 'showdown') { - if (elem.host && elem.host !== Config.routes.client && elem.host !== 'psim.us') { - return null; - } - href = elem.pathname; - } else { - if (elem.host !== location.host) { - return null; - } - href = elem.pathname; - } - const roomid = href.slice(1); - if (!/^[a-z0-9-]*$/.test(roomid)) { - return null; // not a roomid - } - const redirects = /^(appeals?|rooms?suggestions?|suggestions?|adminrequests?|bugs?|bugreports?|rules?|faq|credits?|news|privacy|contact|dex|insecure)$/; - if (redirects.test(roomid)) return null; - return roomid as RoomID; - } static containingRoomid(elem: HTMLElement) { let curElem: HTMLElement | null = elem; while (curElem) { diff --git a/testclient-beta.html b/testclient-beta.html index ad02dce6a8..ed08d9093b 100644 --- a/testclient-beta.html +++ b/testclient-beta.html @@ -53,6 +53,30 @@

      '; } From e4f73b4b02d59b230b7a69dfd2243e9aa5aa0608 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Fri, 23 Jul 2021 21:49:56 +0530 Subject: [PATCH 166/770] Check for Neutralizing Gas in tooltips (#1845) --- src/battle-tooltips.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 591a3134ca..7e73a32799 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -62,6 +62,8 @@ class ModifiableValue { this.comment.push(` (${abilityName} suppressed by Gastro Acid)`); return false; } + // Check for Neutralizing Gas + if (!this.pokemon?.effectiveAbility(this.serverPokemon)) return false; return true; } tryWeather(weatherName?: string) { From 8f8d79191f3f8676660d2667718a098bfd0d84a1 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 28 Jul 2021 19:10:26 -0700 Subject: [PATCH 167/770] Start modularizing some battle files (#1842) Progress is very incomplete, but this is mostly an experiment to establish this as possible at all. What's going on here is that we're using `remove-import-export` so the `import` and `export` statements just disappear after compiling (everything's still a global). This allows us to piecewise convert files to modules. So we're just using TypeScript to keep track of dependencies, and also to make it easier to use these files in other projects later on. I've tried to avoid circular dependencies, but there's one between `battle-animations` and `battle-animations-moves`. --- src/battle-animations-moves.ts | 4 +++- src/battle-animations.ts | 27 +++++++++++++++-------- src/battle-log.ts | 28 ++++++++++++++++-------- src/battle-scene-stub.ts | 12 ++++++---- src/battle-sound.ts | 4 ++-- src/battle.ts | 29 ++++++++++++++---------- src/globals.d.ts | 40 +++++++++++++++------------------- tslint.json | 1 + 8 files changed, 86 insertions(+), 59 deletions(-) diff --git a/src/battle-animations-moves.ts b/src/battle-animations-moves.ts index ec39628e9c..81c8a06816 100644 --- a/src/battle-animations-moves.ts +++ b/src/battle-animations-moves.ts @@ -9,7 +9,9 @@ * @license CC0-1.0 */ -const BattleMoveAnims: AnimTable = { +import {AnimTable, BattleOtherAnims} from './battle-animations'; + +export const BattleMoveAnims: AnimTable = { taunt: { anim(scene, [attacker, defender]) { BattleOtherAnims.dance.anim(scene, [attacker, defender]); diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 396eb19342..b86378367d 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -11,6 +11,12 @@ * @license MIT */ +import type {Battle, Pokemon, Side, WeatherState} from './battle'; +import type {BattleSceneStub} from './battle-scene-stub'; +import {BattleMoveAnims} from './battle-animations-moves'; +import {BattleLog} from './battle-log'; +import {BattleBGM, BattleSound} from './battle-sound'; + /* Most of this file is: CC0 (public domain) @@ -30,7 +36,7 @@ This license DOES NOT extend to any other files in this repository. */ -class BattleScene { +export class BattleScene implements BattleSceneStub { battle: Battle; animating = true; acceleration = 1; @@ -234,7 +240,7 @@ class BattleScene { } else { this.$frame.append('


      '); this.$frame.find('div.playbutton button[name=play-muted]').click(() => { - this.battle.setMute(true); + this.setMute(true); this.battle.play(); }); } @@ -244,6 +250,9 @@ class BattleScene { this.$frame.find('div.playbutton').remove(); this.updateBgm(); } + setMute(muted: boolean) { + BattleSound.setMute(muted); + } wait(time: number) { if (!this.animating) return; this.timeOffset += time; @@ -589,7 +598,7 @@ class BattleScene { } else { let statustext = ''; if (pokemon.hp !== pokemon.maxhp) { - statustext += Pokemon.getHPText(pokemon); + statustext += pokemon.getHPText(); } if (pokemon.status) { if (statustext) statustext += '|'; @@ -1643,7 +1652,7 @@ class BattleScene { } } -interface ScenePos { +export interface ScenePos { /** - left, + right */ x?: number; /** - down, + up */ @@ -1669,7 +1678,7 @@ interface InitScenePos { display?: string; } -class Sprite { +export class Sprite { scene: BattleScene; $el: JQuery = null!; sp: SpriteData; @@ -1732,7 +1741,7 @@ class Sprite { } } -class PokemonSprite extends Sprite { +export class PokemonSprite extends Sprite { // HTML strings are constructed from this table and stored back in it to cache them protected static statusTable: {[id: string]: [string, 'good' | 'bad' | 'neutral'] | null | string} = { formechange: null, @@ -2795,7 +2804,7 @@ interface AnimData { prepareAnim?(scene: BattleScene, args: PokemonSprite[]): void; residualAnim?(scene: BattleScene, args: PokemonSprite[]): void; } -type AnimTable = {[k: string]: AnimData}; +export type AnimTable = {[k: string]: AnimData}; const BattleEffects: {[k: string]: SpriteData} = { wisp: { @@ -3112,7 +3121,7 @@ const BattleBackdrops = [ 'bg-skypillar.jpg', ]; -const BattleOtherAnims: AnimTable = { +export const BattleOtherAnims: AnimTable = { hitmark: { anim(scene, [attacker]) { scene.showEffect('hitmark', { @@ -5698,7 +5707,7 @@ const BattleOtherAnims: AnimTable = { }, }, }; -const BattleStatusAnims: AnimTable = { +export const BattleStatusAnims: AnimTable = { brn: { anim(scene, [attacker]) { scene.showEffect('fireball', { diff --git a/src/battle-log.ts b/src/battle-log.ts index ece0bad608..a45b6c9c16 100644 --- a/src/battle-log.ts +++ b/src/battle-log.ts @@ -13,7 +13,17 @@ * @license MIT */ -class BattleLog { +import type {BattleScene} from './battle-animations'; + +// Caja +declare const html4: any; +declare const html: any; + +// defined in battle-log-misc +declare function MD5(input: string): string; +declare function formatText(input: string, isTrusted?: boolean): string; + +export class BattleLog { elem: HTMLDivElement; innerElem: HTMLDivElement; scene: BattleScene | null = null; @@ -358,7 +368,7 @@ class BattleLog { addSpacer() { this.addDiv('spacer battle-history', '
      '); } - changeUhtml(id: string, html: string, forceAdd?: boolean) { + changeUhtml(id: string, htmlSrc: string, forceAdd?: boolean) { id = toID(id); const classContains = ' uhtml-' + id + ' '; let elements = [] as HTMLDivElement[]; @@ -374,9 +384,9 @@ class BattleLog { } } } - if (html && elements.length && !forceAdd) { + if (htmlSrc && elements.length && !forceAdd) { for (const element of elements) { - element.innerHTML = BattleLog.sanitizeHTML(html); + element.innerHTML = BattleLog.sanitizeHTML(htmlSrc); } this.updateScroll(); return; @@ -384,11 +394,11 @@ class BattleLog { for (const element of elements) { element.parentElement!.removeChild(element); } - if (!html) return; + if (!htmlSrc) return; if (forceAdd) { - this.addDiv('notice uhtml-' + id, BattleLog.sanitizeHTML(html)); + this.addDiv('notice uhtml-' + id, BattleLog.sanitizeHTML(htmlSrc)); } else { - this.prependDiv('notice uhtml-' + id, BattleLog.sanitizeHTML(html)); + this.prependDiv('notice uhtml-' + id, BattleLog.sanitizeHTML(htmlSrc)); } } hideChatFrom(userid: ID, showRevealButton = true, lineCount = 0) { @@ -634,8 +644,8 @@ class BattleLog { case 'uhtml': case 'uhtmlchange': let parts = target.split(','); - let html = parts.slice(1).join(',').trim(); - this.changeUhtml(parts[0], html, cmd === 'uhtml'); + let htmlSrc = parts.slice(1).join(',').trim(); + this.changeUhtml(parts[0], htmlSrc, cmd === 'uhtml'); return ['', '']; case 'raw': return ['chat', BattleLog.sanitizeHTML(target)]; diff --git a/src/battle-scene-stub.ts b/src/battle-scene-stub.ts index b27b7a74fb..99a8dde092 100644 --- a/src/battle-scene-stub.ts +++ b/src/battle-scene-stub.ts @@ -1,4 +1,8 @@ -class BattleSceneStub { +import type {Pokemon, Side} from './battle'; +import type {ScenePos, PokemonSprite} from './battle-animations'; +import type {BattleLog} from './battle-log'; + +export class BattleSceneStub { animating: boolean = false; acceleration: number = NaN; gen: number = NaN; @@ -10,12 +14,12 @@ class BattleSceneStub { log: BattleLog = {add: (args: Args, kwargs?: KWArgs) => {}} as any; abilityActivateAnim(pokemon: Pokemon, result: string): void { } - addPokemonSprite(pokemon: Pokemon) { return null!; } + addPokemonSprite(pokemon: Pokemon): PokemonSprite { return null!; } addSideCondition(siden: number, id: ID, instant?: boolean | undefined): void { } animationOff(): void { } animationOn(): void { } maybeCloseMessagebar(args: Args, kwArgs: KWArgs): boolean { return false; } - closeMessagebar(): void { } + closeMessagebar(): boolean { return false; } damageAnim(pokemon: Pokemon, damage: string | number): void { } destroy(): void { } finishAnimations(): JQuery.Promise, any, any> | undefined { return void(0); } @@ -25,6 +29,7 @@ class BattleSceneStub { updateAcceleration(): void { } message(message: string, hiddenMessage?: string | undefined): void { } pause(): void { } + setMute(muted: boolean): void { } preemptCatchup(): void { } removeSideCondition(siden: number, id: ID): void { } reset(): void { } @@ -68,7 +73,6 @@ class BattleSceneStub { anim(pokemon: Pokemon, end: ScenePos, transition?: string) { } beforeMove(pokemon: Pokemon) { } afterMove(pokemon: Pokemon) { } - unlink(userid: string, showRevealButton = false) { } } if (typeof require === 'function') { diff --git a/src/battle-sound.ts b/src/battle-sound.ts index ae1bac2c2e..5307e73f97 100644 --- a/src/battle-sound.ts +++ b/src/battle-sound.ts @@ -1,5 +1,5 @@ -class BattleBGM { +export class BattleBGM { /** * May be shared with other BGM objects: every battle has its own BattleBGM * object, but two battles with the same music will have the same HTMLAudioElement @@ -100,7 +100,7 @@ class BattleBGM { } } -const BattleSound = new class { +export const BattleSound = new class { soundCache: {[url: string]: HTMLAudioElement | undefined} = {}; bgm: BattleBGM[] = []; diff --git a/src/battle.ts b/src/battle.ts index 7e51d7a829..ceb23d2873 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -27,13 +27,17 @@ * @license MIT */ +import {BattleSceneStub} from './battle-scene-stub'; +import {BattleLog} from './battle-log'; +import {BattleScene, PokemonSprite, BattleStatusAnims} from './battle-animations'; + /** [id, element?, ...misc] */ -type EffectState = any[] & {0: ID}; +export type EffectState = any[] & {0: ID}; /** [name, minTimeLeft, maxTimeLeft] */ -type WeatherState = [string, number, number]; -type HPColor = 'r' | 'y' | 'g'; +export type WeatherState = [string, number, number]; +export type HPColor = 'r' | 'y' | 'g'; -class Pokemon implements PokemonDetails, PokemonHealth { +export class Pokemon implements PokemonDetails, PokemonHealth { name = ''; speciesForme = ''; @@ -570,6 +574,9 @@ class Pokemon implements PokemonDetails, PokemonHealth { } return percentage * maxWidth / 100; } + getHPText(precision = 1) { + return Pokemon.getHPText(this, precision); + } static getHPText(pokemon: PokemonHealth, precision = 1) { if (pokemon.maxhp === 100) return pokemon.hp + '%'; if (pokemon.maxhp !== 48) return (100 * pokemon.hp / pokemon.maxhp).toFixed(precision) + '%'; @@ -583,7 +590,7 @@ class Pokemon implements PokemonDetails, PokemonHealth { } } -class Side { +export class Side { battle: Battle; name = ''; id = ''; @@ -932,7 +939,7 @@ class Side { } } -interface PokemonDetails { +export interface PokemonDetails { details: string; name: string; speciesForme: string; @@ -942,14 +949,14 @@ interface PokemonDetails { ident: string; searchid: string; } -interface PokemonHealth { +export interface PokemonHealth { hp: number; maxhp: number; hpcolor: HPColor | ''; status: StatusName | 'tox' | '' | '???'; fainted?: boolean; } -interface ServerPokemon extends PokemonDetails, PokemonHealth { +export interface ServerPokemon extends PokemonDetails, PokemonHealth { ident: string; details: string; condition: string; @@ -976,8 +983,8 @@ interface ServerPokemon extends PokemonDetails, PokemonHealth { gigantamax: string | false; } -class Battle { - scene: BattleScene | BattleSceneStub; +export class Battle { + scene: BattleSceneStub; sidesSwitched = false; @@ -3669,7 +3676,7 @@ class Battle { } setMute(mute: boolean) { - BattleSound.setMute(mute); + this.scene.setMute(mute); } } diff --git a/src/globals.d.ts b/src/globals.d.ts index 67c82497e6..b81224f6be 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -1,14 +1,5 @@ - - -// dependencies -/////////////// - -// Caja -declare var html4: any; -declare var html: any; - -// data -/////// +// dex data +/////////// declare var BattlePokedex: any; declare var BattleMovedex: any; @@ -16,21 +7,9 @@ declare var BattleAbilities: any; declare var BattleItems: any; declare var BattleAliases: any; declare var BattleStatuses: any; -// declare var BattleMoveAnims: any; -// declare var BattleStatusAnims: any; -// declare var BattleOtherAnims: any; -// declare var BattleBackdrops: any; -// declare var BattleBackdropsThree: any; -// declare var BattleBackdropsFour: any; -// declare var BattleBackdropsFive: any; -// declare var BattleEffects: any; declare var BattlePokemonSprites: any; declare var BattlePokemonSpritesBW: any; -// defined in battle-log-misc -declare function MD5(input: string): string; -declare function formatText(input: string, isTrusted?: boolean): string; - // PS globals ///////////// @@ -43,3 +22,18 @@ declare var app: {user: AnyObject, rooms: AnyObject, ignore?: AnyObject}; interface Window { [k: string]: any; } + +// Temporary globals (exported from modules, used by non-module files) + +// When creating now module files, these should all be commented out +// to make sure they're not being used globally in modules. + +declare var Battle: typeof import('./battle').Battle; +type Battle = import('./battle').Battle; +declare var BattleScene: typeof import('./battle-animations').BattleScene; +type BattleScene = import('./battle-animations').BattleScene; +declare var Pokemon: typeof import('./battle').Pokemon; +type Pokemon = import('./battle').Pokemon; +type ServerPokemon = import('./battle').ServerPokemon; +declare var BattleLog: typeof import('./battle-log').BattleLog; +type BattleLog = import('./battle-log').BattleLog; diff --git a/tslint.json b/tslint.json index 302df64982..280ac9e9a3 100644 --- a/tslint.json +++ b/tslint.json @@ -36,6 +36,7 @@ "no-unnecessary-initializer": false, "object-literal-sort-keys": false, "object-literal-key-quotes": false, + "ordered-imports": false, "trailing-comma": [ true, { From 2b09f5d2037748e5b3e4c48d75f063f764cb2b72 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Thu, 29 Jul 2021 19:28:19 -0400 Subject: [PATCH 168/770] Teambuilder: Fix CAP sprite handling --- src/battle-dex.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 30e8bab0f3..7b78b9fcf5 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -741,10 +741,10 @@ const Dex = new class implements ModdedDex { }; if (pokemon.shiny) spriteData.shiny = true; if (Dex.prefs('nopastgens')) gen = 6; - let xydexExists = (!species.isNonstandard || species.isNonstandard === 'Past') || [ - "pikachustarter", "eeveestarter", "meltan", "melmetal", "fidgit", "stratagem", "tomohawk", "mollux", "crucibelle", "crucibellemega", "kerfluffle", "pajantom", "jumbao", "caribolt", "smokomodo", "snaelstrom", "equilibra", "astrolotl", "scratchet", "pluffle", "smogecko", "pokestarufo", "pokestarufo2", "pokestarbrycenman", "pokestarmt", "pokestarmt2", "pokestargiant", "pokestarhumanoid", "pokestarmonster", "pokestarf00", "pokestarf002", "pokestarspirit", + let xydexExists = (!species.isNonstandard || species.isNonstandard === 'Past' || species.isNonstandard === 'CAP') || [ + "pikachustarter", "eeveestarter", "meltan", "melmetal", "pokestarufo", "pokestarufo2", "pokestarbrycenman", "pokestarmt", "pokestarmt2", "pokestargiant", "pokestarhumanoid", "pokestarmonster", "pokestarf00", "pokestarf002", "pokestarspirit", ].includes(species.id); - if (species.gen === 8) xydexExists = false; + if (species.gen === 8 && species.isNonstandard !== 'CAP') xydexExists = false; if ((!gen || gen >= 6) && xydexExists) { if (species.gen >= 7) { spriteData.x = -6; From 4af1a7ecd574e160aa535f15ec1a866faf0e3a25 Mon Sep 17 00:00:00 2001 From: Annika Date: Sat, 31 Jul 2021 13:14:58 -0700 Subject: [PATCH 169/770] Update banned host message We are going to ban Glitch servers which may be innocent --- js/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client.js b/js/client.js index d9d3e2d827..3c927d1b2c 100644 --- a/js/client.js +++ b/js/client.js @@ -724,7 +724,7 @@ function toId() { } if (Config.server.banned) { - this.addPopupMessage("This server has been deleted for breaking US laws, impersonating PS global staff, or other major rulebreaking."); + this.addPopupMessage("This server has either been deleted for breaking US law or PS global rules, or it is hosted on a platform that's often used to host rulebreaking servers."); return; } From 4d403f0ebe5d173325ba9ca6464361b8888b2010 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 4 Aug 2021 14:56:16 +0530 Subject: [PATCH 170/770] List Shore Up as a good move (#1847) --- src/battle-dex-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 3a6c98462b..a861c35329 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1340,7 +1340,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return !BattleMoveSearch.BAD_STRONG_MOVES.includes(id); } static readonly GOOD_STATUS_MOVES = [ - 'agility', 'aromatherapy', 'auroraveil', 'autotomize', 'banefulbunker', 'batonpass', 'bellydrum', 'bulkup', 'calmmind', 'clangoroussoul', 'coil', 'cottonguard', 'courtchange', 'curse', 'defog', 'destinybond', 'detect', 'disable', 'dragondance', 'drainingkiss', 'encore', 'extremeevoboost', 'geomancy', 'glare', 'haze', 'healbell', 'healingwish', 'healorder', 'heartswap', 'honeclaws', 'kingsshield', 'irondefense', 'leechseed', 'lightscreen', 'lovelykiss', 'lunardance', 'magiccoat', 'maxguard', 'memento', 'milkdrink', 'moonlight', 'morningsun', 'nastyplot', 'naturesmadness', 'noretreat', 'obstruct', 'painsplit', 'partingshot', 'perishsong', 'protect', 'quiverdance', 'recover', 'reflect', 'reflecttype', 'rest', 'roar', 'rockpolish', 'roost', 'shellsmash', 'shiftgear', 'slackoff', 'sleeppowder', 'sleeptalk', 'softboiled', 'spikes', 'spikyshield', 'spore', 'stealthrock', 'stickyweb', 'strengthsap', 'substitute', 'switcheroo', 'swordsdance', 'synthesis', 'tailglow', 'tailwind', 'taunt', 'thunderwave', 'toxic', 'toxicspikes', 'transform', 'trick', 'whirlwind', 'willowisp', 'wish', 'yawn', + 'agility', 'aromatherapy', 'auroraveil', 'autotomize', 'banefulbunker', 'batonpass', 'bellydrum', 'bulkup', 'calmmind', 'clangoroussoul', 'coil', 'cottonguard', 'courtchange', 'curse', 'defog', 'destinybond', 'detect', 'disable', 'dragondance', 'drainingkiss', 'encore', 'extremeevoboost', 'geomancy', 'glare', 'haze', 'healbell', 'healingwish', 'healorder', 'heartswap', 'honeclaws', 'kingsshield', 'irondefense', 'leechseed', 'lightscreen', 'lovelykiss', 'lunardance', 'magiccoat', 'maxguard', 'memento', 'milkdrink', 'moonlight', 'morningsun', 'nastyplot', 'naturesmadness', 'noretreat', 'obstruct', 'painsplit', 'partingshot', 'perishsong', 'protect', 'quiverdance', 'recover', 'reflect', 'reflecttype', 'rest', 'roar', 'rockpolish', 'roost', 'shellsmash', 'shiftgear', 'shoreup', 'slackoff', 'sleeppowder', 'sleeptalk', 'softboiled', 'spikes', 'spikyshield', 'spore', 'stealthrock', 'stickyweb', 'strengthsap', 'substitute', 'switcheroo', 'swordsdance', 'synthesis', 'tailglow', 'tailwind', 'taunt', 'thunderwave', 'toxic', 'toxicspikes', 'transform', 'trick', 'whirlwind', 'willowisp', 'wish', 'yawn', ] as ID[] as readonly ID[]; static readonly GOOD_WEAK_MOVES = [ 'accelerock', 'acrobatics', 'aquajet', 'avalanche', 'bonemerang', 'bouncybubble', 'bulletpunch', 'buzzybuzz', 'circlethrow', 'clearsmog', 'doubleironbash', 'dragondarts', 'dragontail', 'endeavor', 'facade', 'firefang', 'flipturn', 'freezedry', 'frustration', 'geargrind', 'grassknot', 'gyroball', 'hex', 'icefang', 'iceshard', 'iciclespear', 'knockoff', 'lowkick', 'machpunch', 'nightshade', 'nuzzle', 'pikapapow', 'psychocut', 'pursuit', 'quickattack', 'rapidspin', 'return', 'rockblast', 'scorchingsands', 'seismictoss', 'shadowclaw', 'shadowsneak', 'sizzlyslide', 'storedpower', 'stormthrow', 'suckerpunch', 'superfang', 'surgingstrikes', 'tailslap', 'tripleaxel', 'uturn', 'veeveevolley', 'voltswitch', 'watershuriken', 'weatherball', From 86ea7cbf3ba7cb05a7955533dbe09e573e0c793e Mon Sep 17 00:00:00 2001 From: Annika Date: Mon, 6 Sep 2021 17:35:29 -0700 Subject: [PATCH 171/770] Website: Include Section Leaders in the staff FAQ --- website/pages/staff.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/pages/staff.md b/website/pages/staff.md index 6524502a66..ad266befa1 100644 --- a/website/pages/staff.md +++ b/website/pages/staff.md @@ -16,6 +16,8 @@ Room staff have permissions tied specifically to the room they were promoted in, **Room Owners (`#`)** can do all of the above, as well as promote users to Room Moderator, make unsigned declarations, and set the room introduction. +**Section Leaders (`§`)** oversee public chatrooms within their section. + **Global Drivers (`%`)** can warn users both in rooms and globally, mute users for 7 or 60 minutes, lock users from talking for 2 days or a week, forcibly rename users, clear users' statuses, check users' alternate accounts, check logs of past chat and moderation actions in all rooms. **Global Moderators (`@`)** can do all of the above, as well as ban users from the server, do anything a Room Moderator can do, and check users' IP addresses. From 29d21dd46a8ab0294ed06ebfc231d8c583099be8 Mon Sep 17 00:00:00 2001 From: Annika Date: Mon, 6 Sep 2021 17:38:31 -0700 Subject: [PATCH 172/770] Website: Link to the rooms list in the staff FAQ --- website/pages/staff.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/staff.md b/website/pages/staff.md index ad266befa1..63261fdf98 100644 --- a/website/pages/staff.md +++ b/website/pages/staff.md @@ -16,7 +16,7 @@ Room staff have permissions tied specifically to the room they were promoted in, **Room Owners (`#`)** can do all of the above, as well as promote users to Room Moderator, make unsigned declarations, and set the room introduction. -**Section Leaders (`§`)** oversee public chatrooms within their section. +**Section Leaders (`§`)** oversee public chatrooms within their section. You can refer to the [list of rooms](https://www.smogon.com/forums/threads/pok%C3%A9mon-showdown-forum-rules-resources-read-here-first.3570628/#post-6804772) to see who oversees each section. **Global Drivers (`%`)** can warn users both in rooms and globally, mute users for 7 or 60 minutes, lock users from talking for 2 days or a week, forcibly rename users, clear users' statuses, check users' alternate accounts, check logs of past chat and moderation actions in all rooms. From 32f58697d8a43c43eed3b1f37f49cc93a3a94e18 Mon Sep 17 00:00:00 2001 From: Annika Date: Mon, 6 Sep 2021 17:56:32 -0700 Subject: [PATCH 173/770] Support TypeScript 4.4 --- src/battle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle.ts b/src/battle.ts index ceb23d2873..e878d11a4d 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -3533,7 +3533,7 @@ export class Battle { } else { this.runMajor(args, kwArgs, preempt); } - } catch (err) { + } catch (err: any) { this.log(['majorerror', 'Error parsing: ' + str + ' (' + err + ')']); if (err.stack) { let stack = ('' + err.stack).split('\n'); From 370e574d9697619b5d80fa71f88237e18d6c40ee Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 8 Sep 2021 17:39:08 -0400 Subject: [PATCH 174/770] Teambuilder: Fix bugs and implement new policy for STABmons (#1846) --- build-tools/build-indexes | 2 +- src/battle-dex-search.ts | 64 ++++++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 0cff4ab072..3bf2296f76 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -950,7 +950,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const overrideMoveData = {}; BattleTeambuilderTable[gen].overrideMoveData = overrideMoveData; - const overrideMoveKeys = ['accuracy', 'basePower', 'category', 'desc', 'flags', 'pp', 'shortDesc', 'target', 'type']; + const overrideMoveKeys = ['accuracy', 'basePower', 'category', 'desc', 'flags', 'isNonstandard', 'pp', 'shortDesc', 'target', 'type']; for (const id in genData.Moves) { const curEntry = Dex.mod(gen).moves.get(id); const nextEntry = Dex.mod(nextGen).moves.get(id); diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index a861c35329..6dcc0e8c37 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -715,7 +715,7 @@ abstract class BattleTypedSearch { return '' as ID; } protected canLearn(speciesid: ID, moveid: ID) { - if (this.dex.gen >= 8 && this.dex.moves.get(moveid).isNonstandard === 'Past' && this.formatType !== 'natdex') { + if (this.dex.moves.get(moveid).isNonstandard === 'Past' && this.formatType !== 'natdex') { return false; } let genChar = `${this.dex.gen}`; @@ -1416,13 +1416,13 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { if (sketch) { if (move.isMax || move.isZ) continue; if (move.isNonstandard && move.isNonstandard !== 'Past') continue; - if (move.isNonstandard === 'Past' && this.formatType !== 'natdex' && dex.gen === 8) continue; + if (move.isNonstandard === 'Past' && this.formatType !== 'natdex') continue; sketchMoves.push(move.id); } else { if (!(dex.gen < 8 || this.formatType === 'natdex') && move.isZ) continue; if (typeof move.isMax === 'string') continue; if (move.isNonstandard === 'LGPE' && this.formatType !== 'letsgo') continue; - if (move.isNonstandard === 'Past' && this.formatType !== 'natdex' && dex.gen === 8) continue; + if (move.isNonstandard === 'Past' && this.formatType !== 'natdex') continue; moves.push(move.id); } } @@ -1430,30 +1430,46 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { if (this.formatType === 'metronome') moves = ['metronome']; if (isSTABmons) { for (let id in this.getTable()) { - let types: string[] = []; - let baseSpecies = dex.species.get(species.changesFrom || species.name); - if (!species.battleOnly) types.push(...species.types); - let prevo = species.prevo; - while (prevo) { - const prevoSpecies = dex.species.get(prevo); - types.push(...prevoSpecies.types); - prevo = prevoSpecies.prevo; - } - if (species.battleOnly) species = baseSpecies; - const excludedForme = (s: Species) => ['Alola', 'Alola-Totem', 'Galar', 'Galar-Zen'].includes(s.forme); - if (baseSpecies.otherFormes && !['Wormadam', 'Urshifu'].includes(baseSpecies.baseSpecies)) { - if (!excludedForme(species)) types.push(...baseSpecies.types); - for (const formeName of baseSpecies.otherFormes) { - const forme = dex.species.get(formeName); - if (!forme.battleOnly && !excludedForme(forme)) types.push(...forme.types); - } - } - const move = Dex.moves.get(id); - if (!types.includes(move.type)) continue; + const move = dex.moves.get(id); if (moves.includes(move.id)) continue; if (move.gen > dex.gen) continue; if (move.isZ || move.isMax || move.isNonstandard) continue; - moves.push(id); + + const speciesTypes: string[] = []; + const moveTypes: string[] = []; + for (let i = dex.gen; i >= species.gen && i >= move.gen; i--) { + const genDex = Dex.forGen(i); + moveTypes.push(genDex.moves.get(move.name).type); + + const pokemon = genDex.species.get(species.name); + let baseSpecies = genDex.species.get(pokemon.changesFrom || pokemon.name); + if (!pokemon.battleOnly) speciesTypes.push(...pokemon.types); + let prevo = pokemon.prevo; + while (prevo) { + const prevoSpecies = genDex.species.get(prevo); + speciesTypes.push(...prevoSpecies.types); + prevo = prevoSpecies.prevo; + } + if (pokemon.battleOnly && typeof pokemon.battleOnly === 'string') { + species = dex.species.get(pokemon.battleOnly); + } + const excludedForme = (s: Species) => ['Alola', 'Alola-Totem', 'Galar', 'Galar-Zen'].includes(s.forme); + if (baseSpecies.otherFormes && !['Wormadam', 'Urshifu'].includes(baseSpecies.baseSpecies)) { + if (!excludedForme(species)) speciesTypes.push(...baseSpecies.types); + for (const formeName of baseSpecies.otherFormes) { + const forme = dex.species.get(formeName); + if (!forme.battleOnly && !excludedForme(forme)) speciesTypes.push(...forme.types); + } + } + } + let valid = false; + for (let type of moveTypes) { + if (speciesTypes.includes(type)) { + valid = true; + break; + } + } + if (valid) moves.push(id); } } From b30cd0d80dadcc9e26b9086c6250a2e39faed3ea Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 8 Sep 2021 17:40:01 -0400 Subject: [PATCH 175/770] Fix selecting cosmetic formes in old gens (#1849) --- build-tools/build-indexes | 2 +- js/client-teambuilder.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 3bf2296f76..6f6233dbaa 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -936,7 +936,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const nextGenData = Dex.mod(nextGen).data; const overrideSpeciesData = {}; BattleTeambuilderTable[gen].overrideSpeciesData = overrideSpeciesData; - const overrideSpeciesKeys = ['abilities', 'baseStats', 'requiredItem', 'types']; + const overrideSpeciesKeys = ['abilities', 'baseStats', 'cosmeticFormes', 'requiredItem', 'types', 'unreleasedHidden']; for (const id in genData.Pokedex) { const curEntry = genData.Pokedex[id]; const nextEntry = nextGenData.Pokedex[id]; diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index b070fc37a0..d00a111aa7 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -3358,9 +3358,9 @@ this.$el.html(buf).css({'max-width': (4 + spriteSize) * width, 'height': 42 + (4 + spriteSize) * height}); }, setForm: function (form) { - var species = this.room.curTeam.dex.species.get(this.curSet.species); + var species = Dex.species.get(this.curSet.species); if (form && form !== species.form) { - this.curSet.species = this.room.curTeam.dex.species.get(species.baseSpecies + form).name; + this.curSet.species = Dex.species.get(species.baseSpecies + form).name; } else if (!form) { this.curSet.species = species.baseSpecies; } From af72f0bd0f81ad27ca1a293f26e02d8955b40739 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Wed, 8 Sep 2021 15:40:34 -0600 Subject: [PATCH 176/770] Tooltips: Fix Light Ball and Transform-item interaction (#1850) --- src/battle-tooltips.ts | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 7e73a32799..60ea24e298 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -13,13 +13,13 @@ class ModifiableValue { maxValue = 0; comment: string[]; battle: Battle; - pokemon: Pokemon | null; + pokemon: Pokemon; serverPokemon: ServerPokemon; itemName: string; abilityName: string; weatherName: string; isAccuracy = false; - constructor(battle: Battle, pokemon: Pokemon | null, serverPokemon: ServerPokemon) { + constructor(battle: Battle, pokemon: Pokemon, serverPokemon: ServerPokemon) { this.comment = []; this.battle = battle; this.pokemon = pokemon; @@ -1016,25 +1016,27 @@ class BattleTooltips { item = '' as ID; } - const speciesForme = clientPokemon ? clientPokemon.getSpeciesForme() : serverPokemon.speciesForme; - let species = Dex.species.get(speciesForme).baseSpecies; + const species = Dex.species.get(serverPokemon.speciesForme).baseSpecies; + const isTransform = clientPokemon?.volatiles.transform; + const speciesName = isTransform && clientPokemon?.volatiles.formechange?.[1] && this.battle.gen <= 4 ? + this.battle.dex.species.get(clientPokemon.volatiles.formechange[1]).baseSpecies : species; let speedModifiers = []; // check for light ball, thick club, metal/quick powder // the only stat modifying items in gen 2 were light ball, thick club, metal powder - if (item === 'lightball' && species === 'Pikachu') { - if (this.battle.gen >= 4) stats.atk *= 2; + if (item === 'lightball' && speciesName === 'Pikachu' && this.battle.gen !== 4) { + if (this.battle.gen > 4) stats.atk *= 2; stats.spa *= 2; } if (item === 'thickclub') { - if (species === 'Marowak' || species === 'Cubone') { + if (speciesName === 'Marowak' || speciesName === 'Cubone') { stats.atk *= 2; } } - if (species === 'Ditto' && !(clientPokemon && 'transform' in clientPokemon.volatiles)) { + if (speciesName === 'Ditto' && !(clientPokemon && 'transform' in clientPokemon.volatiles)) { if (item === 'quickpowder') { speedModifiers.push(2); } @@ -1915,6 +1917,10 @@ class BattleTooltips { let item = this.battle.dex.items.get(value.serverPokemon.item); let itemName = item.name; let moveName = move.name; + let species = this.battle.dex.species.get(value.serverPokemon.speciesForme); + let isTransform = value.pokemon.volatiles.transform; + let speciesName = isTransform && value.pokemon.volatiles.formechange?.[1] && this.battle.gen <= 4 ? + this.battle.dex.species.get(value.pokemon.volatiles.formechange[1]).baseSpecies : species.baseSpecies; // Plates if (item.onPlate === moveType && !item.zMove) { @@ -1934,9 +1940,15 @@ class BattleTooltips { return value; } + // Light ball is a base power modifier in gen 4 only + if (item.name === 'Light Ball' && this.battle.gen === 4 && speciesName === 'Pikachu') { + value.itemModify(2); + return value; + } + // Pokemon-specific items if (item.name === 'Soul Dew' && this.battle.gen < 7) return value; - if (BattleTooltips.orbUsers[Dex.species.get(value.serverPokemon.speciesForme).baseSpecies] === item.name && + if (BattleTooltips.orbUsers[speciesName] === item.name && [BattleTooltips.orbTypes[item.name], 'Dragon'].includes(moveType)) { value.itemModify(1.2); return value; From 1caf07bc8c096740d264a182bf462e735d5908cc Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 8 Sep 2021 17:41:16 -0400 Subject: [PATCH 177/770] Teambuilder: Support Monotype bans (#1841) --- build-tools/build-indexes | 12 ++++++++++++ src/battle-dex-search.ts | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 6f6233dbaa..200ddb20ac 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -341,6 +341,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const tierTable = {}; const overrideTier = {}; const zuBans = {}; + const monotypeBans = {}; const nonstandardMoves = []; for (const id of pokemon) { const species = Dex.mod(gen).species.get(id); @@ -465,6 +466,12 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); zuBans[species.id] = 1; } } + if (genNum >= 5) { + const format = Dex.formats.get(gen + (isNatDex ? 'nationaldex' : '') + 'monotype'); + if (Dex.formats.getRuleTable(format).isBannedSpecies(species)) { + monotypeBans[species.id] = 1; + } + } } nonstandardMoves.push(...Object.keys(Dex.data.Moves).filter(id => { @@ -481,6 +488,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable['natdex'] = {}; BattleTeambuilderTable['natdex'].tiers = tiers; BattleTeambuilderTable['natdex'].items = items; + BattleTeambuilderTable['natdex'].monotypeBans = monotypeBans; BattleTeambuilderTable['natdex'].formatSlices = formatSlices; } else if (isMetBattle) { BattleTeambuilderTable['metronome'] = {}; @@ -512,6 +520,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable.items = items; BattleTeambuilderTable.overrideTier = overrideTier; BattleTeambuilderTable.zuBans = zuBans; + BattleTeambuilderTable.monotypeBans = monotypeBans; BattleTeambuilderTable.formatSlices = formatSlices; } else { BattleTeambuilderTable[gen] = {}; @@ -522,6 +531,9 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (genNum >= 7) { BattleTeambuilderTable[gen].zuBans = zuBans; } + if (genNum >= 5) { + BattleTeambuilderTable[gen].monotypeBans = monotypeBans; + } if (isDLC1) { BattleTeambuilderTable[gen].nonstandardMoves = nonstandardMoves; BattleTeambuilderTable[gen].learnsets = {}; diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 6dcc0e8c37..f342dfa40a 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -893,6 +893,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { else if (format === 'anythinggoes' || format.endsWith('ag') || format.startsWith('ag')) { tierSet = tierSet.slice(slices.AG); } else if (format.includes('hackmons') || format.endsWith('bh')) tierSet = tierSet.slice(slices.AG); + else if (format === 'monotype') tierSet = tierSet.slice(slices.Uber); else if (format === 'doublesubers') tierSet = tierSet.slice(slices.DUber); else if (format === 'doublesou' && dex.gen > 4) tierSet = tierSet.slice(slices.DOU); else if (format === 'doublesuu') tierSet = tierSet.slice(slices.DUU); @@ -921,6 +922,13 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { }); } + if (format === 'monotype' && dex.gen >= 5) { + tierSet = tierSet.filter(([type, id]) => { + if (id in table.monotypeBans) return false; + return true; + }); + } + if (format === 'vgc2016') { tierSet = tierSet.filter(([type, id]) => { let banned = [ From 1dad120b123a020fd7b4203a9a921d46675dd45e Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 8 Sep 2021 17:42:04 -0400 Subject: [PATCH 178/770] Update move flag names (#1857) --- src/battle-dex-data.ts | 8 ++++---- src/battle-tooltips.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index 3fedcc3452..be44c1bde6 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -1047,12 +1047,14 @@ class Item implements Effect { } interface MoveFlags { - /** Ignores a target's substitute. */ - authentic?: 1 | 0; + /** The move has an animation when used on an ally. */ + allyanim?: 1 | 0; /** Power is multiplied by 1.5 when used by a Pokemon with the Strong Jaw Ability. */ bite?: 1 | 0; /** Has no effect on Pokemon with the Bulletproof Ability. */ bullet?: 1 | 0; + /** Ignores a target's substitute. */ + bypasssub?: 1 | 0; /** The user is unable to make a move between turns. */ charge?: 1 | 0; /** Makes contact. */ @@ -1069,8 +1071,6 @@ interface MoveFlags { heal?: 1 | 0; /** Can be copied by Mirror Move. */ mirror?: 1 | 0; - /** Unknown effect. */ - mystery?: 1 | 0; /** Prevented from being executed or selected in a Sky Battle. */ nonsky?: 1 | 0; /** Has no effect on Grass-type Pokemon, Pokemon with the Overcoat Ability, and Pokemon holding Safety Goggles. */ diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 60ea24e298..2e72eb831b 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -711,7 +711,7 @@ class BattleTooltips { if (!move.flags.protect && !['self', 'allySide'].includes(move.target)) { text += `

      Not blocked by Protect (and Detect, King's Shield, Spiky Shield)

      `; } - if (move.flags.authentic && !(move.flags.sound && this.battle.gen < 6)) { + if (move.flags.bypasssub) { text += `

      Bypasses Substitute (but does not break it)

      `; } if (!move.flags.reflectable && !['self', 'allySide'].includes(move.target) && move.category === 'Status') { From 7422173ffc56f4210451eb35d05272cbc8f1a4ab Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Wed, 8 Sep 2021 15:44:45 -0600 Subject: [PATCH 179/770] Place Section Leaders appropriately in default groups (#1835) --- js/client.js | 19 ++++++++++++------- src/client-main.ts | 13 +++++++++---- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/js/client.js b/js/client.js index 3c927d1b2c..87a50fbcf1 100644 --- a/js/client.js +++ b/js/client.js @@ -2534,39 +2534,44 @@ function toId() { type: 'staff', order: 10006 }, + '\u00a7': { + name: "Section Leader (\u00a7)", + type: 'staff', + order: 10007 + }, '*': { name: "Bot (*)", type: 'normal', - order: 10007 + order: 10008 }, '\u2606': { name: "Player (\u2606)", type: 'normal', - order: 10008 + order: 10009 }, '+': { name: "Voice (+)", type: 'normal', - order: 10009 + order: 10010 }, ' ': { type: 'normal', - order: 10010 + order: 10011 }, '!': { name: "Muted (!)", type: 'punishment', - order: 10011 + order: 10012 }, '✖': { name: "Namelocked (✖)", type: 'punishment', - order: 10012 + order: 10013 }, '\u203d': { name: "Locked (\u203d)", type: 'punishment', - order: 10013 + order: 10014 } }; diff --git a/src/client-main.ts b/src/client-main.ts index a1703dcb4b..8c73287017 100644 --- a/src/client-main.ts +++ b/src/client-main.ts @@ -352,14 +352,19 @@ class PSServer { type: 'staff', order: 106, }, - // by default, unrecognized ranks go here, between driver and bot + '\u00a7': { + name: "Section Leader (\u00a7)", + type: 'staff', + order: 107, + }, + // by default, unrecognized ranks go here, between section leader and bot '*': { name: "Bot (*)", - order: 108, + order: 109, }, '\u2606': { name: "Player (\u2606)", - order: 109, + order: 110, }, '+': { name: "Voice (+)", @@ -385,7 +390,7 @@ class PSServer { }, }; defaultGroup: PSGroup = { - order: 107, + order: 108, }; getGroup(symbol: string | undefined) { return this.groups[(symbol || ' ').charAt(0)] || this.defaultGroup; From 9967b755439ea6fb8b5393fb8deb881603f33411 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Fri, 17 Sep 2021 18:25:30 -0400 Subject: [PATCH 180/770] Teambuilder: Don't show mythicals for Battle Stadium/VGC (#1860) --- src/battle-dex-data.ts | 2 ++ src/battle-dex-search.ts | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index be44c1bde6..dcdf6ae9a6 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -1340,6 +1340,7 @@ class Species implements Effect { readonly color: string; readonly genderRatio: Readonly<{M: number, F: number}> | null; readonly eggGroups: ReadonlyArray; + readonly tags: ReadonlyArray; // format data readonly otherFormes: ReadonlyArray | null; @@ -1389,6 +1390,7 @@ class Species implements Effect { this.color = data.color || ''; this.genderRatio = data.genderRatio || null; this.eggGroups = data.eggGroups || []; + this.tags = data.tags || []; this.otherFormes = data.otherFormes || null; this.cosmeticFormes = data.cosmeticFormes || null; diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index f342dfa40a..39ddbbf088 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -929,12 +929,10 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { }); } - if (format === 'vgc2016') { + if (/^(battlespot|battlestadium|vgc)/g.test(format)) { tierSet = tierSet.filter(([type, id]) => { - let banned = [ - 'deoxys', 'deoxysattack', 'deoxysdefense', 'deoxysspeed', 'mew', 'celebi', 'shaymin', 'shayminsky', 'darkrai', 'victini', 'keldeo', 'keldeoresolute', 'meloetta', 'arceus', 'genesect', 'jirachi', 'manaphy', 'phione', 'hoopa', 'hoopaunbound', 'diancie', 'dianciemega', - ]; - return !(banned.includes(id) || id.startsWith('arceus')); + const species = dex.species.get(id); + return !species.tags.includes('Mythical'); }); } From 6993b9a46421153aa1b19cfd9ec046d75a279f52 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 19 Sep 2021 10:30:17 -0400 Subject: [PATCH 181/770] Gen I-II: Fix Mist text (#1861) --- src/battle-animations.ts | 2 ++ src/battle-text-parser.ts | 6 +++++- src/battle.ts | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index b86378367d..c6434641bb 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -1834,6 +1834,8 @@ export class PokemonSprite extends Sprite { thundercage: ['Thunder Cage', 'bad'], whirlpool: ['Whirlpool', 'bad'], wrap: ['Wrap', 'bad'], + // Gen 1-2 + mist: ['Mist', 'good'], // Gen 1 lightscreen: ['Light Screen', 'good'], reflect: ['Reflect', 'good'], diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 7d234c91bf..63c93c10e7 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -591,6 +591,7 @@ class BattleTextParser { if (kwArgs.damage) templateId = 'activate'; if (kwArgs.block) templateId = 'block'; if (kwArgs.upkeep) templateId = 'upkeep'; + if (id === 'mist' && this.gen <= 2) templateId = 'startGen' + this.gen; if (id === 'reflect' || id === 'lightscreen') templateId = 'startGen1'; if (templateId === 'start' && kwArgs.from?.startsWith('item:')) { templateId += 'FromItem'; @@ -996,7 +997,10 @@ class BattleTextParser { case '-block': { let [, pokemon, effect, move, attacker] = args; const line1 = this.maybeAbility(effect, kwArgs.of || pokemon); - const template = this.template('block', effect); + let id = BattleTextParser.effectId(effect); + let templateId = 'block'; + if (id === 'mist' && this.gen <= 2) templateId = 'blockGen' + this.gen; + const template = this.template(templateId, effect); return line1 + template.replace('[POKEMON]', this.pokemon(pokemon)).replace('[SOURCE]', this.pokemon(attacker || kwArgs.of)).replace('[MOVE]', move); } diff --git a/src/battle.ts b/src/battle.ts index e878d11a4d..81c10415ad 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2540,6 +2540,10 @@ export class Battle { } break; + // Gen 1-2 + case 'mist': + this.scene.resultAnim(poke, 'Mist', 'good'); + break; // Gen 1 case 'lightscreen': this.scene.resultAnim(poke, 'Light Screen', 'good'); From 53573f9f89c450c93fcb785c82c409bd8d79a56a Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sun, 19 Sep 2021 08:30:50 -0600 Subject: [PATCH 182/770] Fix Section Leaders on usercard (#1858) --- js/client.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/client.js b/js/client.js index 87a50fbcf1..b9a7d774d1 100644 --- a/js/client.js +++ b/js/client.js @@ -2604,7 +2604,7 @@ function toId() { var groupName = ((Config.groups[data.roomGroup] || {}).name || ''); var globalGroup = (Config.groups[data.group || Config.defaultGroup || ' '] || null); var globalGroupName = ''; - if (globalGroup && globalGroup.name) { + if (globalGroup && globalGroup.name && toID(globalGroup.name) !== toID(data.customgroup)) { if (globalGroup.type === 'punishment') { groupName = globalGroup.name; } else if (!groupName || groupName === globalGroup.name) { @@ -2630,7 +2630,7 @@ function toId() { if (globalGroupName) { buf += '' + globalGroupName + ''; } - if (data.customgroup) { + if (data.customgroup && toID(data.customgroup) !== toID(globalGroupName || groupName)) { if (groupName || globalGroupName) buf += '
      '; buf += '' + BattleLog.escapeHTML(data.customgroup) + ''; } From b416c28408e213625929ab3c454c3b69c314165b Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sun, 19 Sep 2021 08:31:53 -0600 Subject: [PATCH 183/770] Teambuilder: Add support for Stadium tiers (#1859) --- build-tools/build-indexes | 14 +++++++++++--- src/battle-dex-search.ts | 20 +++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 200ddb20ac..e243700d59 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -322,19 +322,27 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const GENS = [8, 7, 6, 5, 4, 3, 2, 1]; const DOUBLES = GENS.filter(x => x > 2).map(num => -num); const NFE = GENS.map(num => num + 0.3); + const STADIUM = [2.04, 1.04]; const OTHER = [8.4, 8.2, 8.1, -8.4, 7.1, -7.5]; // process.stdout.write("\n "); - for (const genIdent of [...GENS, ...DOUBLES, ...NFE, ...OTHER]) { + for (const genIdent of [...GENS, ...DOUBLES, ...NFE, ...STADIUM, ...OTHER]) { const isLetsGo = (genIdent === 7.1); const isMetBattle = (genIdent === 8.2); const isNFE = (('' + genIdent).endsWith('.3')); const isDLC1 = (genIdent === 8.4 || genIdent === -8.4); const isNatDex = (genIdent === 8.1); + const isStadium = ('' + genIdent).endsWith('.04'); const isDoubles = (genIdent < 0); const isVGC = (genIdent === -7.5); const genNum = Math.floor(isDoubles ? -genIdent : genIdent); - const gen = 'gen' + genNum + (isDLC1 ? 'dlc1' : isLetsGo ? 'letsgo' : ''); + const gen = (() => { + let genStr = 'gen' + genNum; + if (isDLC1) genStr += 'dlc1'; + if (isLetsGo) genStr += 'letsgo'; + if (isStadium) genStr += 'stadium' + (genNum > 1 ? genNum : ''); + return genStr; + })(); // process.stdout.write("" + gen + (isDoubles ? " doubles" : "") + "... "); const pokemon = Object.keys(Dex.data.Pokedex); pokemon.sort(); @@ -553,7 +561,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (isDoubles && genNum > 4) { return ["DUber", "(DUber)", "DOU", "DBL", "(DOU)", "DUU", "(DUU)", "New", "NFE", "LC"]; } - if (gen === 'gen1' || gen === 'gen2' || gen === 'gen3') { + if (gen === 'gen1' || gen === 'gen2' || gen === 'gen3' || isStadium) { return ["Uber", "OU", "(OU)", "UUBL", "UU", "NUBL", "NU", "PUBL", "PU", "NFE", "LC"]; } if (gen === 'gen4') { diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 39ddbbf088..5bc3bf8bf4 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -543,7 +543,8 @@ abstract class BattleTypedSearch { */ set: PokemonSet | null = null; - protected formatType: 'doubles' | 'letsgo' | 'metronome' | 'natdex' | 'nfe' | 'dlc1' | 'dlc1doubles' | null = null; + protected formatType: 'doubles' | 'letsgo' | 'metronome' | 'natdex' | 'nfe' | + 'dlc1' | 'dlc1doubles' | 'stadium' | null = null; /** * Cached copy of what the results list would be with only base filters @@ -582,6 +583,11 @@ abstract class BattleTypedSearch { } format = format.slice(4) as ID; } + if (format.includes('stadium')) { + this.formatType = 'stadium'; + format = format.slice(7) as ID; + if (!format) format = 'ou' as ID; + } if (format === 'vgc2020') this.formatType = 'dlc1doubles'; if (format.includes('doubles') && this.dex.gen > 4 && !this.formatType) this.formatType = 'doubles'; if (format.startsWith('ffa') || format === 'freeforall') this.formatType = 'doubles'; @@ -747,12 +753,14 @@ abstract class BattleTypedSearch { return pokemon.num >= 0 ? String(pokemon.num) : pokemon.tier; } let table = window.BattleTeambuilderTable; - const tableKey = this.formatType === 'doubles' ? `gen${this.dex.gen}doubles` : + const gen = this.dex.gen; + const tableKey = this.formatType === 'doubles' ? `gen${gen}doubles` : this.formatType === 'letsgo' ? 'letsgo' : - this.formatType === 'nfe' ? `gen${this.dex.gen}nfe` : + this.formatType === 'nfe' ? `gen${gen}nfe` : this.formatType === 'dlc1' ? 'gen8dlc1' : this.formatType === 'dlc1doubles' ? 'gen8dlc1doubles' : - `gen${this.dex.gen}`; + this.formatType === 'stadium' ? `gen${gen}stadium${gen > 1 ? gen : ''}` : + `gen${gen}`; if (table && table[tableKey]) { table = table[tableKey]; } @@ -864,6 +872,8 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { } else { table = table['gen8dlc1']; } + } else if (this.formatType === 'stadium') { + table = table['gen' + dex.gen + 'stadium' + (dex.gen > 1 ? dex.gen : '')]; } if (!table.tierSet) { @@ -898,7 +908,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { else if (format === 'doublesou' && dex.gen > 4) tierSet = tierSet.slice(slices.DOU); else if (format === 'doublesuu') tierSet = tierSet.slice(slices.DUU); else if (format === 'doublesnu') tierSet = tierSet.slice(slices.DNU || slices.DUU); - else if (this.formatType === 'letsgo') tierSet = tierSet.slice(slices.Uber); + else if (this.formatType === 'letsgo' || this.formatType === 'stadium') tierSet = tierSet.slice(slices.Uber); // else if (isDoublesOrBS) tierSet = tierSet; else if (!isDoublesOrBS) { tierSet = [ From f9dcb9b5ceeb03dd445c911ab2d02fbe9780d2d0 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sun, 19 Sep 2021 08:32:26 -0600 Subject: [PATCH 184/770] Teambuilder: Support tradebacks (#1862) --- src/battle-dex-search.ts | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 5bc3bf8bf4..7ea70fa018 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -721,27 +721,31 @@ abstract class BattleTypedSearch { return '' as ID; } protected canLearn(speciesid: ID, moveid: ID) { - if (this.dex.moves.get(moveid).isNonstandard === 'Past' && this.formatType !== 'natdex') { + const move = this.dex.moves.get(moveid); + if (move.isNonstandard === 'Past' && this.formatType !== 'natdex') { return false; } - let genChar = `${this.dex.gen}`; + const gen = this.dex.gen; + let genChar = `${gen}`; if ( this.format.startsWith('vgc') || this.format.startsWith('battlespot') || this.format.startsWith('battlestadium') ) { - if (this.dex.gen === 8) { + if (gen === 8) { genChar = 'g'; - } else if (this.dex.gen === 7) { + } else if (gen === 7) { genChar = 'q'; - } else if (this.dex.gen === 6) { + } else if (gen === 6) { genChar = 'p'; } } let learnsetid = this.firstLearnsetid(speciesid); while (learnsetid) { let learnset = BattleTeambuilderTable.learnsets[learnsetid]; - if (learnset && (moveid in learnset) && learnset[moveid].includes(genChar)) { + if (learnset && (moveid in learnset) && (!this.format.startsWith('tradebacks') ? learnset[moveid].includes(genChar) : + learnset[moveid].includes(genChar) || + (learnset[moveid].includes(`${gen + 1}`) && move.gen === gen))) { return true; } learnsetid = this.nextLearnsetid(learnsetid, speciesid); @@ -1374,6 +1378,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { const format = this.format; const isHackmons = (format.includes('hackmons') || format.endsWith('bh')); const isSTABmons = (format.includes('stabmons') || format === 'staaabmons'); + const isTradebacks = format.includes('tradebacks'); const galarBornLegality = (format.includes('battlestadium') || format.startsWith('vgc') && this.dex.gen === 8); const abilityid = this.set ? toID(this.set.ability) : '' as ID; @@ -1384,10 +1389,11 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { let sketchMoves: string[] = []; let sketch = false; let gen = '' + dex.gen; + let lsetTable = BattleTeambuilderTable; + if (this.formatType === 'letsgo') lsetTable = lsetTable['letsgo']; + if (this.formatType?.startsWith('dlc1')) lsetTable = lsetTable['gen8dlc1']; while (learnsetid) { - let learnset = BattleTeambuilderTable.learnsets[learnsetid]; - if (this.formatType === 'letsgo') learnset = BattleTeambuilderTable['letsgo'].learnsets[learnsetid]; - if (this.formatType?.startsWith('dlc1')) learnset = BattleTeambuilderTable['gen8dlc1'].learnsets[learnsetid]; + let learnset = lsetTable.learnsets[learnsetid]; if (learnset) { for (let moveid in learnset) { let learnsetEntry = learnset[moveid]; @@ -1396,7 +1402,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { } */ if (galarBornLegality && !learnsetEntry.includes('g')) { continue; - } else if (!learnsetEntry.includes(gen)) { + } else if (!learnsetEntry.includes(gen) && + (!isTradebacks ? true : !(dex.moves.get(moveid).gen <= dex.gen && learnsetEntry.includes('' + (dex.gen + 1))))) { continue; } if ( From 4ffba0b8089d4daff5bf8884f91e873183e68801 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sun, 19 Sep 2021 16:09:41 -0600 Subject: [PATCH 185/770] Teambuilder: Fix Battle Stadium formats (#1864) --- src/battle-dex-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 7ea70fa018..0e34202fe5 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -583,7 +583,7 @@ abstract class BattleTypedSearch { } format = format.slice(4) as ID; } - if (format.includes('stadium')) { + if (format.startsWith('stadium')) { this.formatType = 'stadium'; format = format.slice(7) as ID; if (!format) format = 'ou' as ID; From 57ee41c8277bd3ac4189b80959b445ea08345284 Mon Sep 17 00:00:00 2001 From: Annika Date: Sun, 19 Sep 2021 15:27:08 -0700 Subject: [PATCH 186/770] Fix e-mail address validation According to [the PHP documentation](https://www.php.net/manual/en/language.operators.precedence.php), && and || are left-associative. --- website/users.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/users.php b/website/users.php index 42352fb882..84fc91eed7 100644 --- a/website/users.php +++ b/website/users.php @@ -266,7 +266,7 @@ } else if ($csrfOk && isset($_POST['googlelogin'])) { $email = $_POST['googlelogin']; $remove = ($email === 'remove'); - if (!$remove && strpos($email, '@') === false || strpos($email, '.') === false) { + if (!$remove && (strpos($email, '@') === false || strpos($email, '.') === false)) { ?>

      Invalid e-mail address ""

      From cb70f73b5d29ba22c11cac198f738b7002fa90ba Mon Sep 17 00:00:00 2001 From: Leonard Craft III Date: Tue, 21 Sep 2021 21:01:55 -0500 Subject: [PATCH 187/770] Fix client commands on certain Android devices (#1863) --- js/client-chat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-chat.js b/js/client-chat.js index 94f9b06e33..63c7b2d51f 100644 --- a/js/client-chat.js +++ b/js/client-chat.js @@ -449,7 +449,7 @@ } } - switch (cmd.toLowerCase()) { + switch (toID(cmd)) { case 'chal': case 'chall': case 'challenge': From 608e3919ac7a6b54ca98bad87d516cffe7ba96ae Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Tue, 21 Sep 2021 22:02:16 -0400 Subject: [PATCH 188/770] Fix Teambuilder button not working after copying a Pokemon (#1865) --- js/client-teambuilder.js | 2 +- src/battle-dex-search.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index d00a111aa7..8a7e697c8e 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -1482,7 +1482,7 @@ var buf = ''; for (var i = 0; i < this.clipboardCount(); i++) { var res = this.clipboard[i]; - var species = this.curTeam.dex.species.get(res.species); + var species = Dex.species.get(res.species); buf += '
      '; buf += '
      '; diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 0e34202fe5..82251e6df1 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -946,7 +946,8 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { if (/^(battlespot|battlestadium|vgc)/g.test(format)) { tierSet = tierSet.filter(([type, id]) => { const species = dex.species.get(id); - return !species.tags.includes('Mythical'); + const baseSpecies = dex.species.get(species.baseSpecies); + return !baseSpecies.tags.includes('Mythical'); }); } From 318a7b29a055ff8db05d0e8a29e45fb734702e66 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Thu, 23 Sep 2021 10:51:36 -0400 Subject: [PATCH 189/770] Update Pokemon icons sheet --- src/battle-dex-data.ts | 3 ++- src/battle-dex.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index dcdf6ae9a6..1e3954c79d 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -503,7 +503,7 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { nohface: 1344 + 18, monohm: 1344 + 19, duohm: 1344 + 20, - // protowatt: 1344 + 21, + protowatt: 1344 + 21, voodoll: 1344 + 22, mumbao: 1344 + 23, fawnifer: 1344 + 24, @@ -515,6 +515,7 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { justyke: 1344 + 30, solotl: 1344 + 31, miasmite: 1344 + 32, + dorsoil: 1344 + 33, }; const BattlePokemonIconIndexesLeft: {[id: string]: number} = { diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 7b78b9fcf5..952d50cf64 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -722,7 +722,7 @@ const Dex = new class implements ModdedDex { let top = Math.floor(num / 12) * 30; let left = (num % 12) * 40; let fainted = ((pokemon as Pokemon | ServerPokemon)?.fainted ? `;opacity:.3;filter:grayscale(100%) brightness(.5)` : ``); - return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v5) no-repeat scroll -${left}px -${top}px${fainted}`; + return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v6) no-repeat scroll -${left}px -${top}px${fainted}`; } getTeambuilderSpriteData(pokemon: any, gen: number = 0): TeambuilderSpriteData { From 07130c33b64269ad3fe9499ffd692dab26f632f1 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 29 Sep 2021 20:31:16 -0400 Subject: [PATCH 190/770] Tooltips: Fix Heal Bell getting affected by Pressure (#1867) --- src/battle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle.ts b/src/battle.ts index 81c10415ad..71f8874834 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1431,7 +1431,7 @@ export class Battle { if ( !target && this.gameType === 'singles' && - !['self', 'allies', 'allySide', 'adjacentAlly', 'adjacentAllyOrSelf'].includes(move.target) + !['self', 'allies', 'allySide', 'adjacentAlly', 'adjacentAllyOrSelf', 'allyTeam'].includes(move.target) ) { // Hardcode for moves without a target in singles foeTargets.push(pokemon.side.foe.active[0]); From 280bc6da706c08ab7e49135c516fc0daf5e751a0 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 29 Sep 2021 21:19:36 -0400 Subject: [PATCH 191/770] Teambuilder: Use Gen 7 VGC tier slices for all VGC/BS formats (#1868) --- build-tools/build-indexes | 26 ++++++++++---------------- src/battle-dex-search.ts | 36 ++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index e243700d59..0656db2a06 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -310,9 +310,6 @@ console.log("DONE"); * Build teambuilder-tables.js *********************************************************/ -const restrictedLegends = ['Mewtwo', 'Lugia', 'Ho-Oh', 'Kyogre', 'Groudon', 'Rayquaza', 'Dialga', 'Palkia', 'Giratina', 'Reshiram', 'Zekrom', 'Kyurem', 'Xerneas', 'Yveltal', 'Zygarde', 'Cosmog', 'Cosmoem', 'Solgaleo', 'Lunala', 'Necrozma']; -const mythicals = ['Mew', 'Celebi', 'Jirachi', 'Deoxys', 'Phione', 'Manaphy', 'Darkrai', 'Shaymin', 'Arceus', 'Victini', 'Keldeo', 'Meloetta', 'Genesect', 'Diancie', 'Hoopa', 'Volcanion', 'Greninja-Ash', 'Magearna', 'Marshadow', 'Zeraora']; - process.stdout.write("Building `data/teambuilder-tables.js`... "); { @@ -321,20 +318,21 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); let buf = '// DO NOT EDIT - automatically built with build-tools/build-indexes\n\n'; const GENS = [8, 7, 6, 5, 4, 3, 2, 1]; const DOUBLES = GENS.filter(x => x > 2).map(num => -num); + const VGC = GENS.filter(x => x > 3).map(num => -num - 0.5); const NFE = GENS.map(num => num + 0.3); const STADIUM = [2.04, 1.04]; - const OTHER = [8.4, 8.2, 8.1, -8.4, 7.1, -7.5]; + const OTHER = [8.4, 8.2, 8.1, -8.4, 7.1]; // process.stdout.write("\n "); - for (const genIdent of [...GENS, ...DOUBLES, ...NFE, ...STADIUM, ...OTHER]) { + for (const genIdent of [...GENS, ...DOUBLES, ...VGC, ...NFE, ...STADIUM, ...OTHER]) { const isLetsGo = (genIdent === 7.1); const isMetBattle = (genIdent === 8.2); - const isNFE = (('' + genIdent).endsWith('.3')); + const isNFE = ('' + genIdent).endsWith('.3'); const isDLC1 = (genIdent === 8.4 || genIdent === -8.4); const isNatDex = (genIdent === 8.1); const isStadium = ('' + genIdent).endsWith('.04'); const isDoubles = (genIdent < 0); - const isVGC = (genIdent === -7.5); + const isVGC = ('' + genIdent).endsWith('.5'); const genNum = Math.floor(isDoubles ? -genIdent : genIdent); const gen = (() => { let genStr = 'gen' + genNum; @@ -353,6 +351,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const nonstandardMoves = []; for (const id of pokemon) { const species = Dex.mod(gen).species.get(id); + const baseSpecies = Dex.mod(gen).species.get(species.baseSpecies); if (species.gen > genNum) continue; const tier = (() => { if (isNatDex) { @@ -414,22 +413,17 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); return tier; } if (isLetsGo) { - let baseSpecies = Dex.mod(gen).species.get(species.baseSpecies); let validNum = (baseSpecies.num <= 151 && species.num >= 1) || [808, 809].includes(baseSpecies.num); if (!validNum) return 'Illegal'; if (species.forme && !['Alola', 'Mega', 'Mega-X', 'Mega-Y', 'Starter'].includes(species.forme)) return 'Illegal'; return species.tier; } if (isVGC) { + if (species.isNonstandard && species.isNonstandard !== 'Gigantamax') return 'Illegal'; + if (baseSpecies.tags.includes('Mythical')) return 'Mythical'; + if (baseSpecies.tags.includes('Restricted Legendary')) return 'Restricted Legendary'; if (species.tier === 'NFE') return 'NFE'; - if (species.tier === 'LC') return 'NFE'; - if (species.tier === 'Illegal' || species.tier === 'Unreleased') return 'Illegal'; - if (restrictedLegends.includes(species.name) || restrictedLegends.includes(species.baseSpecies)) { - return 'Restricted Legendary'; - } - if (mythicals.includes(species.name) || mythicals.includes(species.baseSpecies)) { - return 'Mythical'; - } + if (species.tier === 'LC') return 'LC'; return 'Regular'; } if (species.tier === 'CAP' || species.tier === 'CAP NFE' || species.tier === 'CAP LC') { diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 82251e6df1..9288101caf 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -588,6 +588,7 @@ abstract class BattleTypedSearch { format = format.slice(7) as ID; if (!format) format = 'ou' as ID; } + if (format.startsWith('vgc')) this.formatType = 'doubles'; if (format === 'vgc2020') this.formatType = 'dlc1doubles'; if (format.includes('doubles') && this.dex.gen > 4 && !this.formatType) this.formatType = 'doubles'; if (format.startsWith('ffa') || format === 'freeforall') this.formatType = 'doubles'; @@ -840,8 +841,8 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { getBaseResults(): SearchRow[] { const format = this.format; if (!format) return this.getDefaultResults(); - const requirePentagon = format === 'battlespotsingles' || format === 'battledoubles' || format.startsWith('vgc'); - let isDoublesOrBS = this.formatType === 'doubles'; + const isVGCOrBS = format.startsWith('battlespot') || format.startsWith('battlestadium') || format.startsWith('vgc'); + let isDoublesOrBS = isVGCOrBS || this.formatType === 'doubles'; const dex = this.dex; let table = BattleTeambuilderTable; @@ -850,13 +851,12 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { if (dex.gen < 8) { table = table['gen' + dex.gen]; } - } else if (dex.gen === 7 && requirePentagon) { + } else if (isVGCOrBS) { table = table['gen' + dex.gen + 'vgc']; - isDoublesOrBS = true; } else if (table['gen' + dex.gen + 'doubles'] && dex.gen > 4 && this.formatType !== 'letsgo' && this.formatType !== 'dlc1doubles' && ( - format.includes('doubles') || format.includes('vgc') || format.includes('triples') || - format.endsWith('lc') || format.endsWith('lcuu') || format === 'freeforall' || format.startsWith('ffa') + format.includes('doubles') || format.includes('triples') || format.endsWith('lc') || + format.endsWith('lcuu') || format === 'freeforall' || format.startsWith('ffa') )) { table = table['gen' + dex.gen + 'doubles']; isDoublesOrBS = true; @@ -890,12 +890,16 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { let tierSet: SearchRow[] = table.tierSet; let slices: {[k: string]: number} = table.formatSlices; if (format === 'ubers' || format === 'uber') tierSet = tierSet.slice(slices.Uber); - else if (format === 'vgc2017') tierSet = tierSet.slice(slices.Regular); - else if (format === 'vgc2018') tierSet = tierSet.slice(slices.Regular); - else if (format.startsWith('vgc2019')) tierSet = tierSet.slice(slices["Restricted Legendary"]); - else if (format === 'battlespotsingles') tierSet = tierSet.slice(slices.Regular); - else if (format === 'battlespotdoubles') tierSet = tierSet.slice(slices.Regular); - else if (format === 'ou') tierSet = tierSet.slice(slices.OU); + else if (isVGCOrBS) { + if ( + format === 'vgc2010' || format === 'vgc2016' || format.startsWith('vgc2019') || + format.endsWith('series8') || format.endsWith('series10') + ) { + tierSet = tierSet.slice(slices["Restricted Legendary"]); + } else { + tierSet = tierSet.slice(slices.Regular); + } + } else if (format === 'ou') tierSet = tierSet.slice(slices.OU); else if (format === 'uu') tierSet = tierSet.slice(slices.UU); else if (format === 'ru') tierSet = tierSet.slice(slices.RU || slices.UU); else if (format === 'nu') tierSet = tierSet.slice(slices.NU || slices.UU); @@ -943,14 +947,6 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { }); } - if (/^(battlespot|battlestadium|vgc)/g.test(format)) { - tierSet = tierSet.filter(([type, id]) => { - const species = dex.species.get(id); - const baseSpecies = dex.species.get(species.baseSpecies); - return !baseSpecies.tags.includes('Mythical'); - }); - } - // Filter out Gmax Pokemon from standard tier selection if (!/^(battlestadium|vgc|doublesubers)/g.test(format)) { tierSet = tierSet.filter(([type, id]) => { From 618713293676e6013cfd624eab6c13ea83f1700d Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 29 Sep 2021 21:30:28 -0400 Subject: [PATCH 192/770] Add support for Let's Go move data overrides (#1829) --- build-tools/build-indexes | 39 +++++++++++++++++++++++++++++++-------- js/client-teambuilder.js | 9 +++++++++ src/battle-dex-search.ts | 11 +++++++---- src/battle-dex.ts | 8 ++++++-- src/battle.ts | 3 +++ 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 0656db2a06..6b98a69642 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -503,11 +503,11 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable[gen + 'nfe'].overrideTier = overrideTier; BattleTeambuilderTable[gen + 'nfe'].formatSlices = formatSlices; } else if (isLetsGo) { - BattleTeambuilderTable['letsgo'] = {}; - BattleTeambuilderTable['letsgo'].learnsets = {}; - BattleTeambuilderTable['letsgo'].tiers = tiers; - BattleTeambuilderTable['letsgo'].overrideTier = overrideTier; - BattleTeambuilderTable['letsgo'].formatSlices = formatSlices; + BattleTeambuilderTable['gen7letsgo'] = {}; + BattleTeambuilderTable['gen7letsgo'].learnsets = {}; + BattleTeambuilderTable['gen7letsgo'].tiers = tiers; + BattleTeambuilderTable['gen7letsgo'].overrideTier = overrideTier; + BattleTeambuilderTable['gen7letsgo'].formatSlices = formatSlices; } else if (isVGC) { BattleTeambuilderTable[gen + 'vgc'] = {}; BattleTeambuilderTable[gen + 'vgc'].tiers = tiers; @@ -892,9 +892,9 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (!validNum) continue; if (species.forme && !['Alola', 'Mega', 'Mega-X', 'Mega-Y', 'Starter'].includes(species.forme)) continue; const learnset = LGLearnsets[id].learnset; - BattleTeambuilderTable['letsgo'].learnsets[id] = {}; + BattleTeambuilderTable['gen7letsgo'].learnsets[id] = {}; for (const moveid in learnset) { - BattleTeambuilderTable['letsgo'].learnsets[id][moveid] = '7'; + BattleTeambuilderTable['gen7letsgo'].learnsets[id][moveid] = '7'; } } const DLC1Learnsets = Dex.mod('gen8dlc1').data.Learnsets; @@ -964,7 +964,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const overrideMoveData = {}; BattleTeambuilderTable[gen].overrideMoveData = overrideMoveData; - const overrideMoveKeys = ['accuracy', 'basePower', 'category', 'desc', 'flags', 'isNonstandard', 'pp', 'shortDesc', 'target', 'type']; + const overrideMoveKeys = ['accuracy', 'basePower', 'category', 'desc', 'flags', 'isNonstandard', 'pp', 'priority', 'shortDesc', 'target', 'type']; for (const id in genData.Moves) { const curEntry = Dex.mod(gen).moves.get(id); const nextEntry = Dex.mod(nextGen).moves.get(id); @@ -1014,6 +1014,29 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } } + // + // Let's Go + // + + { + const LGDex = Dex.mod('gen7letsgo'); + const LGData = LGDex.data; + + const overrideMoveData = {}; + BattleTeambuilderTable['gen7letsgo'].overrideMoveData = overrideMoveData; + const overrideMoveKeys = ['basePower', 'desc', 'pp', 'priority', 'shortDesc']; + for (const id in LGData.Moves) { + const modEntry = LGDex.moves.get(id); + const parentEntry = Dex.mod('gen7').moves.get(id); + for (const key of overrideMoveKeys) { + if (JSON.stringify(modEntry[key]) !== JSON.stringify(parentEntry[key])) { + if (!overrideMoveData[id]) overrideMoveData[id] = {}; + overrideMoveData[id][key] = modEntry[key]; + } + } + } + } + buf += `exports.BattleTeambuilderTable = JSON.parse('${JSON.stringify(BattleTeambuilderTable).replace(/['\\]/g, "\\$&")}');\n\n`; fs.writeFileSync('data/teambuilder-tables.js', buf); diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 8a7e697c8e..a375e2b06f 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -21,6 +21,9 @@ this.curTeam.iconCache = '!'; this.curTeam.gen = this.getGen(this.curTeam.format); this.curTeam.dex = Dex.forGen(this.curTeam.gen); + if (this.curTeam.format.includes('letsgo')) { + this.curTeam.dex = Dex.mod('gen7letsgo'); + } Storage.activeSetList = this.curSetList; } }, @@ -679,6 +682,9 @@ this.curTeam.iconCache = '!'; this.curTeam.gen = this.getGen(this.curTeam.format); this.curTeam.dex = Dex.forGen(this.curTeam.gen); + if (this.curTeam.format.includes('letsgo')) { + this.curTeam.dex = Dex.mod('gen7letsgo'); + } Storage.activeSetList = this.curSetList = Storage.unpackTeam(this.curTeam.team); this.curTeamIndex = i; this.update(); @@ -1438,6 +1444,9 @@ this.curTeam.format = format; this.curTeam.gen = this.getGen(this.curTeam.format); this.curTeam.dex = Dex.forGen(this.curTeam.gen); + if (this.curTeam.format.includes('letsgo')) { + this.curTeam.dex = Dex.mod('gen7letsgo'); + } this.save(); if (this.curTeam.gen === 5 && !Dex.loadedSpriteData['bw']) Dex.loadSpriteData('bw'); this.update(); diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 9288101caf..f2dbabc48b 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -592,7 +592,10 @@ abstract class BattleTypedSearch { if (format === 'vgc2020') this.formatType = 'dlc1doubles'; if (format.includes('doubles') && this.dex.gen > 4 && !this.formatType) this.formatType = 'doubles'; if (format.startsWith('ffa') || format === 'freeforall') this.formatType = 'doubles'; - if (format.includes('letsgo')) this.formatType = 'letsgo'; + if (format.includes('letsgo')) { + this.formatType = 'letsgo'; + this.dex = Dex.mod('gen7letsgo' as ID); + } if (format.includes('nationaldex') || format.startsWith('nd') || format.includes('natdex')) { format = (format.startsWith('nd') ? format.slice(2) : format.includes('natdex') ? format.slice(6) : format.slice(11)) as ID; @@ -760,7 +763,7 @@ abstract class BattleTypedSearch { let table = window.BattleTeambuilderTable; const gen = this.dex.gen; const tableKey = this.formatType === 'doubles' ? `gen${gen}doubles` : - this.formatType === 'letsgo' ? 'letsgo' : + this.formatType === 'letsgo' ? 'gen7letsgo' : this.formatType === 'nfe' ? `gen${gen}nfe` : this.formatType === 'dlc1' ? 'gen8dlc1' : this.formatType === 'dlc1doubles' ? 'gen8dlc1doubles' : @@ -863,7 +866,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { } else if (dex.gen < 8 && !this.formatType) { table = table['gen' + dex.gen]; } else if (this.formatType === 'letsgo') { - table = table['letsgo']; + table = table['gen7letsgo']; } else if (this.formatType === 'natdex') { table = table['natdex']; } else if (this.formatType === 'metronome') { @@ -1387,7 +1390,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { let sketch = false; let gen = '' + dex.gen; let lsetTable = BattleTeambuilderTable; - if (this.formatType === 'letsgo') lsetTable = lsetTable['letsgo']; + if (this.formatType === 'letsgo') lsetTable = lsetTable['gen7letsgo']; if (this.formatType?.startsWith('dlc1')) lsetTable = lsetTable['gen8dlc1']; while (learnsetid) { let learnset = lsetTable.learnsets[learnsetid]; diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 952d50cf64..8e8cc05d34 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -836,7 +836,7 @@ class ModdedDex { pokeballs: string[] | null = null; constructor(modid: ID) { this.modid = modid; - let gen = parseInt(modid.slice(3), 10); + const gen = parseInt(modid.substr(3, 1), 10); if (!modid.startsWith('gen') || !gen) throw new Error("Unsupported modid"); this.gen = gen; } @@ -860,6 +860,10 @@ class ModdedDex { if (this.gen <= 3 && data.category !== 'Status') { data.category = Dex.getGen3Category(data.type); } + const table = window.BattleTeambuilderTable[this.modid]; + if (this.modid === 'gen7letsgo' && id in table.overrideMoveData) { + Object.assign(data, table.overrideMoveData[id]); + } const move = new Move(id, name, data); this.cache.Moves[id] = move; @@ -934,7 +938,7 @@ class ModdedDex { Object.assign(data, table.overrideSpeciesData[id]); } } - if (this.gen < 3) { + if (this.gen < 3 || this.modid === 'gen7letsgo') { data.abilities = {0: "None"}; } diff --git a/src/battle.ts b/src/battle.ts index 71f8874834..58260bb816 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -3212,6 +3212,9 @@ export class Battle { this.messageFadeTime = 40; this.isBlitz = true; } + if (this.tier.includes(`Let's Go`)) { + this.dex = Dex.mod('gen7letsgo' as ID); + } this.log(args); break; } From 0c037a9578e3e12a74ad16e638a63d3d2be47f14 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Wed, 29 Sep 2021 23:08:27 -0400 Subject: [PATCH 193/770] Teambuilder: Fix input for Let's Go --- src/battle-dex.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 8e8cc05d34..0661627bd0 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -939,7 +939,7 @@ class ModdedDex { } } if (this.gen < 3 || this.modid === 'gen7letsgo') { - data.abilities = {0: "None"}; + data.abilities = {0: "No Ability"}; } const table = window.BattleTeambuilderTable[this.modid]; From f003dd54c192284231973db39d59e39fda0c3022 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Fri, 1 Oct 2021 21:49:43 -0600 Subject: [PATCH 194/770] Add teambuilder support for Multibility (#1869) --- js/client-teambuilder.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index a375e2b06f..9eaa9f8738 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -2906,6 +2906,8 @@ case 'item': if (id in BattleMovedex && this.curTeam.format == "gen8fortemons") { val = BattleMovedex[id].name; + } else if (id in BattleAbilities && this.curTeam.format == "gen8multibility") { + val = BattleAbilities[id].name; } else { val = (id in BattleItems ? BattleItems[id].name : ''); } From d918eb69e3798c30b2ece535562d377047931778 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Thu, 7 Oct 2021 18:55:37 -0400 Subject: [PATCH 195/770] Fix Wishiwashi forme change animations --- src/battle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle.ts b/src/battle.ts index 58260bb816..ca052287cf 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2368,7 +2368,7 @@ export class Battle { let poke = this.getPokemon(args[1])!; let species = Dex.species.get(args[2]); let fromeffect = Dex.getEffect(kwArgs.from); - let isCustomAnim = false; + let isCustomAnim = species.name.startsWith('Wishiwashi'); poke.removeVolatile('typeadd' as ID); poke.removeVolatile('typechange' as ID); if (this.gen >= 7) poke.removeVolatile('autotomize' as ID); From e1e254e8712118efbd0d201d720c6ddd37637dfe Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 9 Oct 2021 22:06:40 -0400 Subject: [PATCH 196/770] Teambuilder: Show Ferroseed as legal in Gen 8 LC (#1872) --- build-tools/build-indexes | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 6b98a69642..dbbb04e525 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -448,16 +448,14 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (!tierTable[tier]) tierTable[tier] = []; tierTable[tier].push(id); - if (gen === 'gen7' && id in {ferroseed:1} && tier !== 'LC') { - if (!tierTable['LC']) tierTable['LC'] = []; - tierTable['LC'].push(id); - } else if (gen === 'gen6' && id in {ferroseed:1, pawniard:1, vullaby:1} && tier !== 'LC') { - if (!tierTable['LC']) tierTable['LC'] = []; - tierTable['LC'].push(id); - } else if (gen === 'gen5' && id in {misdreavus:1, ferroseed:1} && tier !== 'LC') { - if (!tierTable['LC']) tierTable['LC'] = []; - tierTable['LC'].push(id); - } else if (gen === 'gen4' && id in {clamperl:1, diglett:1, gligar:1, hippopotas:1, snover:1, wynaut:1} && tier !== 'LC') { + if ( + tier !== 'LC' && + (gen === 'gen8' && id === 'ferroseed') || + (gen === 'gen7' && id === 'ferroseed') || + (gen === 'gen6' && ['ferroseed', 'pawniard', 'vullaby'].includes(id)) || + (gen === 'gen5' && id === 'ferroseed') || + (gen === 'gen4' && ['clamperl', 'diglett', 'gligar', 'hippopotas', 'snover', 'wynaut'].includes(id)) + ) { if (!tierTable['LC']) tierTable['LC'] = []; tierTable['LC'].push(id); } From 1fae99d6bcbb25ff35021615e6129cb3ab4d101c Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 9 Oct 2021 22:10:27 -0400 Subject: [PATCH 197/770] Teambuilder: Don't show Gmax options for Gmax formes (#1873) --- js/client-teambuilder.js | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 9eaa9f8738..e2f8d22c6c 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -1207,10 +1207,8 @@ buf += '' + (set.hpType || 'Dark') + ''; } } - if (this.curTeam.gen === 8) { - if (species.canGigantamax || species.name.indexOf('-Gmax') >= 0) { - buf += '' + (set.gigantamax ? 'Yes' : 'No') + ''; - } + if (this.curTeam.gen === 8 && (species.canGigantamax || species.forme === 'Gmax')) { + buf += '' + (set.gigantamax || species.forme === 'Gmax' ? 'Yes' : 'No') + ''; } } buf += '
      '; @@ -2596,16 +2594,14 @@ buf += ''; buf += '

    '; - if (species.canGigantamax) { - buf += '
    '; - buf += ' '; - buf += ''; - buf += '

    '; - } - if (species.name.indexOf('-Gmax') >= 0) { - buf += '
    '; - buf += ' '; - buf += ''; + if (species.canGigantamax || species.forme === 'Gmax') { + buf += '
    '; + if (species.forme === 'Gmax') { + buf += 'Yes'; + } else { + buf += ' '; + buf += ''; + } buf += '
    '; } } @@ -2718,12 +2714,8 @@ } buf += '' + (set.shiny ? 'Yes' : 'No') + ''; if (!isLetsGo && (this.curTeam.gen < 8 || isNatDex)) buf += '' + (set.hpType || 'Dark') + ''; - if (this.curTeam.gen === 8) { - if (species.canGigantamax) { - buf += '' + (set.gigantamax ? 'Yes' : 'No') + ''; - } else if (species.name.indexOf('-Gmax') >= 0) { - buf += 'Yes'; - } + if (this.curTeam.gen === 8 && (species.canGigantamax || species.forme === 'Gmax')) { + buf += '' + (set.gigantamax || species.forme === 'Gmax' ? 'Yes' : 'No') + ''; } } this.$('button[name=details]').html(buf); From d334977d8bd586871054f5aba2e308298759a40e Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 4 Aug 2021 17:48:14 -0400 Subject: [PATCH 198/770] Update to PHP 5 constructors We had an old constructor in a library that was preventing an upgrade to PHP 8. --- website/lib/panels.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/lib/panels.lib.php b/website/lib/panels.lib.php index 1f1f7a7576..3793d6b91e 100644 --- a/website/lib/panels.lib.php +++ b/website/lib/panels.lib.php @@ -9,7 +9,7 @@ class Panels { var $root; var $name; - function Panels() { + function __construct() { global $psconfig; if (@$psconfig['root']) $this->root = $psconfig['root']; From 5dc7b44240cf56b725da275e2973fe0e0bc19296 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sun, 10 Oct 2021 00:42:59 -0400 Subject: [PATCH 199/770] Fix link to HTTPS site The old system of defaulting to HTTP because of bugs in HTTPS hasn't been necessary in a very long time; we even switched to always-HTTPS a few years ago. Fixes https://github.com/smogon/pokemon-showdown/issues/8466 --- website/index.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/website/index.php b/website/index.php index bf4b75b500..a75d108d69 100644 --- a/website/index.php +++ b/website/index.php @@ -27,11 +27,6 @@ function servercmp($a, $b) { $page = 'home'; $pageTitle = "Home"; -$externProtocol = 'http:'; -if ($_SERVER['REQUEST_URI'] === '/secure') { - $externProtocol = ''; -} - $serverbits = ''; $serverbitscache = __DIR__ . '/../config/userbitscache.html'; $lastmodified = @filemtime($serverbitscache); @@ -54,7 +49,7 @@ function servercmp($a, $b) { foreach ($PokemonServers as &$server) { $server['sortorder'] = $sortorder++; if ($server['id'] === 'showdown') { - $server['uri'] = $externProtocol . '//' . $psconfig['routes']['client']; + $server['uri'] = '//' . $psconfig['routes']['client']; } else { $server['uri'] = 'http://' . $server['id'] . '.psim.us'; } @@ -133,7 +128,7 @@ function servercmp($a, $b) { Play (insecure mode) - Play online + Play online

  • '; buf += ''; - var btnClass = 'button' + (!this.curSetList.length ? ' disabled' : ''); + var btnClass = 'button' + (!this.curSetList.length || app.isDisconnected ? ' disabled' : ''); buf += '
  • '; } if (!this.curSetList.length) { From b0d27560e9c0ae72c08c8e60493c0ba9d2211315 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 13 Oct 2021 22:42:17 -0400 Subject: [PATCH 201/770] Fix renderPokemonRow for Dex (#1876) --- js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/search.js b/js/search.js index fc63a6a705..54eba66afa 100644 --- a/js/search.js +++ b/js/search.js @@ -331,7 +331,7 @@ return buf; } - var gen = this.engine.dex.gen; + var gen = this.engine ? this.engine.dex.gen : 8; // type buf += ''; From eadef3247e3a6432285fbd2f5f19e4f28712aa43 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 14 Oct 2021 23:31:05 -0400 Subject: [PATCH 202/770] Teambuilder: Support sorting in reverse (#1875) --- src/battle-dex-search.ts | 51 ++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index f2dbabc48b..886a0ef342 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -72,6 +72,7 @@ class DexSearch { * Pokemon) and name (for everything else). */ sortCol: string | null = null; + reverseSort = false; /** * Filters for the search result. Does not include the two base filters @@ -103,7 +104,7 @@ class DexSearch { } this.query = query; if (!query) { - this.results = this.typedSearch?.getResults(this.filters, this.sortCol) || []; + this.results = this.typedSearch?.getResults(this.filters, this.sortCol, this.reverseSort) || []; } else { this.results = this.textSearch(query); } @@ -174,9 +175,15 @@ class DexSearch { toggleSort(sortCol: string) { if (this.sortCol === sortCol) { - this.sortCol = null; + if (!this.reverseSort) { + this.reverseSort = true; + } else { + this.sortCol = null; + this.reverseSort = false; + } } else { this.sortCol = sortCol; + this.reverseSort = false; } this.results = null; } @@ -623,7 +630,7 @@ abstract class BattleTypedSearch { } if (!searchType || !this.set) return; } - getResults(filters?: SearchFilter[] | null, sortCol?: string | null): SearchRow[] { + getResults(filters?: SearchFilter[] | null, sortCol?: string | null, reverseSort?: boolean): SearchRow[] { if (sortCol === 'type') { return [this.sortRow!, ...BattleTypeSearch.prototype.getDefaultResults.call(this)]; } else if (sortCol === 'category') { @@ -682,10 +689,10 @@ abstract class BattleTypedSearch { if (sortCol) { results = results.filter(([rowType]) => rowType === this.searchType); - results = this.sort(results, sortCol); + results = this.sort(results, sortCol, reverseSort); if (illegalResults) { illegalResults = illegalResults.filter(([rowType]) => rowType === this.searchType); - illegalResults = this.sort(illegalResults, sortCol); + illegalResults = this.sort(illegalResults, sortCol, reverseSort); } } @@ -792,7 +799,7 @@ abstract class BattleTypedSearch { abstract getDefaultResults(): SearchRow[]; abstract getBaseResults(): SearchRow[]; abstract filter(input: SearchRow, filters: string[][]): boolean; - abstract sort(input: SearchRow[], sortCol: string): SearchRow[]; + abstract sort(input: SearchRow[], sortCol: string, reverseSort?: boolean): SearchRow[]; } class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { @@ -985,12 +992,13 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { } return true; } - sort(results: SearchRow[], sortCol: string) { + sort(results: SearchRow[], sortCol: string, reverseSort?: boolean) { + const sortOrder = reverseSort ? -1 : 1; if (['hp', 'atk', 'def', 'spa', 'spd', 'spe'].includes(sortCol)) { return results.sort(([rowType1, id1], [rowType2, id2]) => { const stat1 = this.dex.species.get(id1).baseStats[sortCol as StatName]; const stat2 = this.dex.species.get(id2).baseStats[sortCol as StatName]; - return stat2 - stat1; + return (stat2 - stat1) * sortOrder; }); } else if (sortCol === 'bst') { return results.sort(([rowType1, id1], [rowType2, id2]) => { @@ -998,13 +1006,13 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { const base2 = this.dex.species.get(id2).baseStats; const bst1 = base1.hp + base1.atk + base1.def + base1.spa + base1.spd + base1.spe; const bst2 = base2.hp + base2.atk + base2.def + base2.spa + base2.spd + base2.spe; - return bst2 - bst1; + return (bst2 - bst1) * sortOrder; }); } else if (sortCol === 'name') { return results.sort(([rowType1, id1], [rowType2, id2]) => { const name1 = id1; const name2 = id2; - return name1 < name2 ? -1 : name1 > name2 ? 1 : 0; + return (name1 < name2 ? -1 : name1 > name2 ? 1 : 0) * sortOrder; }); } throw new Error("invalid sortcol"); @@ -1093,7 +1101,7 @@ class BattleAbilitySearch extends BattleTypedSearch<'ability'> { } return true; } - sort(results: SearchRow[], sortCol: string | null): SearchRow[] { + sort(results: SearchRow[], sortCol: string | null, reverseSort?: boolean): SearchRow[] { throw new Error("invalid sortcol"); } } @@ -1155,7 +1163,7 @@ class BattleItemSearch extends BattleTypedSearch<'item'> { } return true; } - sort(results: SearchRow[], sortCol: string | null): SearchRow[] { + sort(results: SearchRow[], sortCol: string | null, reverseSort?: boolean): SearchRow[] { throw new Error("invalid sortcol"); } } @@ -1544,7 +1552,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { } return true; } - sort(results: SearchRow[], sortCol: string): SearchRow[] { + sort(results: SearchRow[], sortCol: string, reverseSort?: boolean): SearchRow[] { + const sortOrder = reverseSort ? -1 : 1; switch (sortCol) { case 'power': let powerTable: {[id: string]: number | undefined} = { @@ -1560,7 +1569,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { let move2 = this.dex.moves.get(id2); let pow1 = move1.basePower || powerTable[id1] || (move1.category === 'Status' ? -1 : 1400); let pow2 = move2.basePower || powerTable[id2] || (move2.category === 'Status' ? -1 : 1400); - return pow2 - pow1; + return (pow2 - pow1) * sortOrder; }); case 'accuracy': return results.sort(([rowType1, id1], [rowType2, id2]) => { @@ -1568,13 +1577,19 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { let accuracy2 = this.dex.moves.get(id2).accuracy || 0; if (accuracy1 === true) accuracy1 = 101; if (accuracy2 === true) accuracy2 = 101; - return accuracy2 - accuracy1; + return (accuracy2 - accuracy1) * sortOrder; }); case 'pp': return results.sort(([rowType1, id1], [rowType2, id2]) => { let pp1 = this.dex.moves.get(id1).pp || 0; let pp2 = this.dex.moves.get(id2).pp || 0; - return pp2 - pp1; + return (pp2 - pp1) * sortOrder; + }); + case 'name': + return results.sort(([rowType1, id1], [rowType2, id2]) => { + const name1 = id1; + const name2 = id2; + return (name1 < name2 ? -1 : name1 > name2 ? 1 : 0) * sortOrder; }); } throw new Error("invalid sortcol"); @@ -1598,7 +1613,7 @@ class BattleCategorySearch extends BattleTypedSearch<'category'> { filter(row: SearchRow, filters: string[][]): boolean { throw new Error("invalid filter"); } - sort(results: SearchRow[], sortCol: string | null): SearchRow[] { + sort(results: SearchRow[], sortCol: string | null, reverseSort?: boolean): SearchRow[] { throw new Error("invalid sortcol"); } } @@ -1620,7 +1635,7 @@ class BattleTypeSearch extends BattleTypedSearch<'type'> { filter(row: SearchRow, filters: string[][]): boolean { throw new Error("invalid filter"); } - sort(results: SearchRow[], sortCol: string | null): SearchRow[] { + sort(results: SearchRow[], sortCol: string | null, reverseSort?: boolean): SearchRow[] { throw new Error("invalid sortcol"); } } From 670828d162965f3a488d989c52adb4ae463eb52f Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sat, 23 Oct 2021 22:32:50 -0400 Subject: [PATCH 203/770] Stop interpreting .html files in URLs as rooms --- js/client.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/client.js b/js/client.js index b9a7d774d1..77395f21ba 100644 --- a/js/client.js +++ b/js/client.js @@ -817,6 +817,7 @@ function toId() { if (!Config.testclient && location.search && window.history) { history.replaceState(null, null, location.pathname); } + if (fragment && fragment.includes('.')) fragment = ''; this.fragment = fragment = toRoomid(fragment || ''); if (this.initialFragment === undefined) this.initialFragment = fragment; this.tryJoinRoom(fragment); From c2aa10821c709beb031389d1a37e938e06f5c2af Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sat, 23 Oct 2021 22:42:37 -0400 Subject: [PATCH 204/770] Fix connecting to localhost servers Fixes https://github.com/smogon/pokemon-showdown/issues/8484 --- js/client.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/js/client.js b/js/client.js index 77395f21ba..9052b5d43b 100644 --- a/js/client.js +++ b/js/client.js @@ -733,6 +733,19 @@ function toId() { var protocol = (Config.server.port === 443 || Config.server.https) ? 'https' : 'http'; Config.server.host = $.trim(Config.server.host); try { + if (Config.server.host === 'localhost') { + // connecting to localhost from psim.us is now banned as of Chrome 94 + // thanks Docker for having vulns + // https://wicg.github.io/cors-rfc1918 + // anyway, this affects SockJS because it makes HTTP requests to localhost + // but it turns out that making direct WebSocket connections to localhost is + // still supported, so we'll just bypass SockJS and use WebSocket directly. + console.log("Bypassing SockJS for localhost"); + console.log('ws' + protocol.slice('4') + '://' + Config.server.host + ':' + Config.server.port + Config.sockjsprefix + '/websocket'); + return new WebSocket( + 'ws' + protocol.slice('4') + '://' + Config.server.host + ':' + Config.server.port + Config.sockjsprefix + '/websocket' + ); + } return new SockJS( protocol + '://' + Config.server.host + ':' + Config.server.port + Config.sockjsprefix, [], {timeout: 5 * 60 * 1000} From 43c2dccc8d24ef029e4cb59a322307710b025de0 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sat, 23 Oct 2021 22:47:28 -0400 Subject: [PATCH 205/770] Fix absolute URLs in CSS files (These images weren't working when opened in `file:` URLs) --- style/client.css | 4 ++-- style/client2.css | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/style/client.css b/style/client.css index 3abd637721..0d135a95de 100644 --- a/style/client.css +++ b/style/client.css @@ -13,7 +13,7 @@ body { font-size: 11pt; font-family: Verdana, Helvetica, Arial, sans-serif; - /* see http://pokemonshowdown.com/credits */ + /* see https://pokemonshowdown.com/credits */ background: #344b6c url(../fx/client-bg-charizards.jpg) no-repeat left center fixed; -webkit-background-size: cover; -moz-background-size: cover; @@ -3230,7 +3230,7 @@ a.ilink.yours { .avatarlist button { width: 80px; height: 80px; - background: transparent url(//play.pokemonshowdown.com/sprites/trainers-sheet.png) no-repeat scroll 0px 0px; + background: transparent url(https://play.pokemonshowdown.com/sprites/trainers-sheet.png) no-repeat scroll 0px 0px; } .bglist button span { display: block; diff --git a/style/client2.css b/style/client2.css index cebfb6385a..65b03b1fe2 100644 --- a/style/client2.css +++ b/style/client2.css @@ -13,7 +13,7 @@ body { font-size: 11pt; font-family: Verdana, Helvetica, Arial, sans-serif; - /* see http://pokemonshowdown.com/credits */ + /* see https://pokemonshowdown.com/credits */ background: #344b6c url(../fx/client-bg-charizards.jpg) no-repeat left center fixed; -webkit-background-size: cover; -moz-background-size: cover; @@ -1981,7 +1981,7 @@ a.ilink.yours { .avatarlist button { width: 80px; height: 80px; - background: transparent url(//play.pokemonshowdown.com/sprites/trainers-sheet.png) no-repeat scroll 0px 0px; + background: transparent url(https://play.pokemonshowdown.com/sprites/trainers-sheet.png) no-repeat scroll 0px 0px; } .bglist button span { display: block; From d3ac6c449d75168416971bca367e57582e058ea6 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Sun, 24 Oct 2021 14:04:46 -0500 Subject: [PATCH 206/770] UI for laddering multi battles with a partner (#1739) --- js/client-mainmenu.js | 18 +++++++++++++++++- js/client.js | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index b9e5ee35cf..0db6d4ef39 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -19,7 +19,8 @@ 'blur textarea': 'onBlurPM', 'click .spoiler': 'clickSpoiler', 'click button.formatselect': 'selectFormat', - 'click button.teamselect': 'selectTeam' + 'click button.teamselect': 'selectTeam', + 'keyup input': 'selectTeammate' }, initialize: function () { this.$el.addClass('scrollable'); @@ -43,6 +44,8 @@ buf += ''; } @@ -274,6 +277,15 @@ buf += '

    '; $challenge.html(buf); }, + + selectTeammate: function (e) { + if (e.currentTarget.name !== 'teammate' || e.keyCode !== 13) return; + var partner = toID(e.currentTarget.value); + if (!partner.length) return; + app.send('/requestpartner ' + partner + ',' + this.format); + e.currentTarget.value = ''; + }, + openPM: function (name, dontFocus) { var userid = toID(name); var $pmWindow = this.$pmBox.find('.pm-window-' + userid); @@ -1256,6 +1268,10 @@ app.rooms[''].curTeamIndex = -1; var $teamButton = this.sourceEl.closest('form').find('button[name=team]'); if ($teamButton.length) $teamButton.replaceWith(app.rooms[''].renderTeams(format)); + var $partnerLabels = $('label[name=partner]'); + $partnerLabels.each(function (i, label) { + label.style.display = BattleFormats[format].partner ? '' : 'none'; + }); } this.sourceEl.val(format).html(BattleLog.escapeFormat(format) || '(Select a format)'); diff --git a/js/client.js b/js/client.js index 9052b5d43b..7bec58440d 100644 --- a/js/client.js +++ b/js/client.js @@ -1259,6 +1259,7 @@ function toId() { var searchShow = true; var challengeShow = true; var tournamentShow = true; + var partner = false; var team = null; var teambuilderLevel = null; var lastCommaIndex = name.lastIndexOf(','); @@ -1270,6 +1271,7 @@ function toId() { if (!(code & 4)) challengeShow = false; if (!(code & 8)) tournamentShow = false; if (code & 16) teambuilderLevel = 50; + if (code & 32) partner = true; } else { // Backwards compatibility: late 0.9.0 -> 0.10.0 if (name.substr(name.length - 2) === ',#') { // preset teams @@ -1335,6 +1337,7 @@ function toId() { tournamentShow: tournamentShow, rated: searchShow && id.substr(4, 7) !== 'unrated', teambuilderLevel: teambuilderLevel, + partner: partner, teambuilderFormat: teambuilderFormat, isTeambuilderFormat: isTeambuilderFormat, effectType: 'Format' From 94f90f6c8b41f6cb131ee9b8b70096973bcc8232 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 24 Oct 2021 15:51:58 -0400 Subject: [PATCH 207/770] Teambuilder: Show Restricted Legendaries for Series 11 (#1878) --- src/battle-dex-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 886a0ef342..77a030eaf2 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -903,7 +903,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { else if (isVGCOrBS) { if ( format === 'vgc2010' || format === 'vgc2016' || format.startsWith('vgc2019') || - format.endsWith('series8') || format.endsWith('series10') + format.endsWith('series10') || format.endsWith('series11') ) { tierSet = tierSet.slice(slices["Restricted Legendary"]); } else { From 45b82c1ce6507fab7bd6b36f84c762e550f8d139 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 24 Oct 2021 15:52:41 -0400 Subject: [PATCH 208/770] Teambuilder: Show Acid Armor as a good move (#1877) --- src/battle-dex-search.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 77a030eaf2..f75faf0d1d 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1293,6 +1293,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return species.baseSpecies === 'Keldeo' || this.formatType === 'doubles'; case 'infestation': return moves.includes('stickyweb'); + case 'irondefense': + return !moves.includes('acidarmor'); case 'irontail': return dex.gen > 5 && !moves.includes('ironhead') && !moves.includes('gunkshot') && !moves.includes('poisonjab'); case 'jumpkick': @@ -1368,7 +1370,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return !BattleMoveSearch.BAD_STRONG_MOVES.includes(id); } static readonly GOOD_STATUS_MOVES = [ - 'agility', 'aromatherapy', 'auroraveil', 'autotomize', 'banefulbunker', 'batonpass', 'bellydrum', 'bulkup', 'calmmind', 'clangoroussoul', 'coil', 'cottonguard', 'courtchange', 'curse', 'defog', 'destinybond', 'detect', 'disable', 'dragondance', 'drainingkiss', 'encore', 'extremeevoboost', 'geomancy', 'glare', 'haze', 'healbell', 'healingwish', 'healorder', 'heartswap', 'honeclaws', 'kingsshield', 'irondefense', 'leechseed', 'lightscreen', 'lovelykiss', 'lunardance', 'magiccoat', 'maxguard', 'memento', 'milkdrink', 'moonlight', 'morningsun', 'nastyplot', 'naturesmadness', 'noretreat', 'obstruct', 'painsplit', 'partingshot', 'perishsong', 'protect', 'quiverdance', 'recover', 'reflect', 'reflecttype', 'rest', 'roar', 'rockpolish', 'roost', 'shellsmash', 'shiftgear', 'shoreup', 'slackoff', 'sleeppowder', 'sleeptalk', 'softboiled', 'spikes', 'spikyshield', 'spore', 'stealthrock', 'stickyweb', 'strengthsap', 'substitute', 'switcheroo', 'swordsdance', 'synthesis', 'tailglow', 'tailwind', 'taunt', 'thunderwave', 'toxic', 'toxicspikes', 'transform', 'trick', 'whirlwind', 'willowisp', 'wish', 'yawn', + 'acidarmor', 'agility', 'aromatherapy', 'auroraveil', 'autotomize', 'banefulbunker', 'batonpass', 'bellydrum', 'bulkup', 'calmmind', 'clangoroussoul', 'coil', 'cottonguard', 'courtchange', 'curse', 'defog', 'destinybond', 'detect', 'disable', 'dragondance', 'drainingkiss', 'encore', 'extremeevoboost', 'geomancy', 'glare', 'haze', 'healbell', 'healingwish', 'healorder', 'heartswap', 'honeclaws', 'kingsshield', 'leechseed', 'lightscreen', 'lovelykiss', 'lunardance', 'magiccoat', 'maxguard', 'memento', 'milkdrink', 'moonlight', 'morningsun', 'nastyplot', 'naturesmadness', 'noretreat', 'obstruct', 'painsplit', 'partingshot', 'perishsong', 'protect', 'quiverdance', 'recover', 'reflect', 'reflecttype', 'rest', 'roar', 'rockpolish', 'roost', 'shellsmash', 'shiftgear', 'shoreup', 'slackoff', 'sleeppowder', 'sleeptalk', 'softboiled', 'spikes', 'spikyshield', 'spore', 'stealthrock', 'stickyweb', 'strengthsap', 'substitute', 'switcheroo', 'swordsdance', 'synthesis', 'tailglow', 'tailwind', 'taunt', 'thunderwave', 'toxic', 'toxicspikes', 'transform', 'trick', 'whirlwind', 'willowisp', 'wish', 'yawn', ] as ID[] as readonly ID[]; static readonly GOOD_WEAK_MOVES = [ 'accelerock', 'acrobatics', 'aquajet', 'avalanche', 'bonemerang', 'bouncybubble', 'bulletpunch', 'buzzybuzz', 'circlethrow', 'clearsmog', 'doubleironbash', 'dragondarts', 'dragontail', 'endeavor', 'facade', 'firefang', 'flipturn', 'freezedry', 'frustration', 'geargrind', 'grassknot', 'gyroball', 'hex', 'icefang', 'iceshard', 'iciclespear', 'knockoff', 'lowkick', 'machpunch', 'nightshade', 'nuzzle', 'pikapapow', 'psychocut', 'pursuit', 'quickattack', 'rapidspin', 'return', 'rockblast', 'scorchingsands', 'seismictoss', 'shadowclaw', 'shadowsneak', 'sizzlyslide', 'storedpower', 'stormthrow', 'suckerpunch', 'superfang', 'surgingstrikes', 'tailslap', 'tripleaxel', 'uturn', 'veeveevolley', 'voltswitch', 'watershuriken', 'weatherball', From 03f1889236809d3897019a18c61206f4fb5b9e3e Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Sun, 24 Oct 2021 15:31:15 -0500 Subject: [PATCH 209/770] Fix selecting a partner (#1879) --- js/client-mainmenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index 0db6d4ef39..ca9961f32a 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -282,7 +282,7 @@ if (e.currentTarget.name !== 'teammate' || e.keyCode !== 13) return; var partner = toID(e.currentTarget.value); if (!partner.length) return; - app.send('/requestpartner ' + partner + ',' + this.format); + app.send('/requestpartner ' + partner + ',' + this.curFormat); e.currentTarget.value = ''; }, From 35f80248073eb6aeb2530609be23d9b14bbf248f Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Tue, 26 Oct 2021 21:13:39 -0400 Subject: [PATCH 210/770] Teambuilder: Fix some LC Pokemon showing twice (#1881) --- build-tools/build-indexes | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index dbbb04e525..e6179df621 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -450,11 +450,13 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if ( tier !== 'LC' && - (gen === 'gen8' && id === 'ferroseed') || - (gen === 'gen7' && id === 'ferroseed') || - (gen === 'gen6' && ['ferroseed', 'pawniard', 'vullaby'].includes(id)) || - (gen === 'gen5' && id === 'ferroseed') || - (gen === 'gen4' && ['clamperl', 'diglett', 'gligar', 'hippopotas', 'snover', 'wynaut'].includes(id)) + ( + (gen === 'gen8' && id === 'ferroseed') || + (gen === 'gen7' && id === 'ferroseed') || + (gen === 'gen6' && ['ferroseed', 'pawniard', 'vullaby'].includes(id)) || + (gen === 'gen5' && id === 'ferroseed') || + (gen === 'gen4' && ['clamperl', 'diglett', 'gligar', 'hippopotas', 'snover', 'wynaut'].includes(id)) + ) ) { if (!tierTable['LC']) tierTable['LC'] = []; tierTable['LC'].push(id); From bda53f80271bc2594d08c87648d5ee0b957e82b5 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sat, 30 Oct 2021 14:10:56 -0400 Subject: [PATCH 211/770] Remove a reference to Lodash in replay-embed (replay-embed is used to play back downloaded replay files) In #907, we forgot to update a reference from `lodash.compat` to `lodash.core`. Nothing broke, though, so this was never noticed. lodash is no longer a dependency of most modern PS files (we've switched to `ps-polyfill`, mostly). So it's better to just remove the dependency here. (Also add a header comment documenting the file a little.) --- js/replay-embed.template.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/js/replay-embed.template.js b/js/replay-embed.template.js index c63dfd2b07..d0cee2e1c4 100644 --- a/js/replay-embed.template.js +++ b/js/replay-embed.template.js @@ -1,3 +1,19 @@ +/** + * Replay embed + * + * This file is used to play back downloaded replay files, and can also be + * used by third parties to embed PS replays. The protocol data to replay + * should be in + * ` + * + * This could let them steal the secrets. In modern times, browsers + * are protected against this kind of attack, but our `]` adds some + * safety for older browsers. + * + * Adding `]` to the beginning makes sure that the output is a syntax + * error in JS, so treating it as a JS file will simply crash and fail. + */ + private $outPrefix = ']'; private $outArray = array(); public function __construct($handlers) { From 6cd9a91b53e7619c2e7a8d5216dbc4057eea63b6 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Thu, 18 Nov 2021 17:21:11 -0700 Subject: [PATCH 222/770] Add BDSP teambuilder support (#1889) * Finish client stuff * Add BDSP doubles support * Fix build --- build-tools/build-indexes | 27 ++++++++++++++-- js/client-teambuilder.js | 39 ++++++++++++++++++----- src/battle-dex-data.ts | 2 ++ src/battle-dex-search.ts | 66 ++++++++++++++++++++++++++++----------- 4 files changed, 105 insertions(+), 29 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index e6179df621..a279d6caa7 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -321,11 +321,12 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const VGC = GENS.filter(x => x > 3).map(num => -num - 0.5); const NFE = GENS.map(num => num + 0.3); const STADIUM = [2.04, 1.04]; - const OTHER = [8.4, 8.2, 8.1, -8.4, 7.1]; + const OTHER = [8.6, 8.4, 8.2, 8.1, -8.4, -8.6, 7.1]; // process.stdout.write("\n "); for (const genIdent of [...GENS, ...DOUBLES, ...VGC, ...NFE, ...STADIUM, ...OTHER]) { const isLetsGo = (genIdent === 7.1); + const isBDSP = (genIdent === 8.6 || genIdent === -8.6); const isMetBattle = (genIdent === 8.2); const isNFE = ('' + genIdent).endsWith('.3'); const isDLC1 = (genIdent === 8.4 || genIdent === -8.4); @@ -338,6 +339,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); let genStr = 'gen' + genNum; if (isDLC1) genStr += 'dlc1'; if (isLetsGo) genStr += 'letsgo'; + if (isBDSP) genStr += 'bdsp'; if (isStadium) genStr += 'stadium' + (genNum > 1 ? genNum : ''); return genStr; })(); @@ -508,6 +510,15 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable['gen7letsgo'].tiers = tiers; BattleTeambuilderTable['gen7letsgo'].overrideTier = overrideTier; BattleTeambuilderTable['gen7letsgo'].formatSlices = formatSlices; + } else if (isBDSP && !isDoubles) { + BattleTeambuilderTable['gen8bdsp'] = {}; + BattleTeambuilderTable['gen8bdsp'].learnsets = {}; + BattleTeambuilderTable['gen8bdsp'].tiers = tiers; + BattleTeambuilderTable['gen8bdsp'].items = items; + BattleTeambuilderTable['gen8bdsp'].overrideTier = overrideTier; + BattleTeambuilderTable['gen8bdsp'].formatSlices = formatSlices; + BattleTeambuilderTable['gen8bdsp'].nonstandardMoves = Dex.mod('gen8bdsp').moves.all() + .filter(x => x.isNonstandard).map(x => x.id); } else if (isVGC) { BattleTeambuilderTable[gen + 'vgc'] = {}; BattleTeambuilderTable[gen + 'vgc'].tiers = tiers; @@ -546,8 +557,8 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (isNatDex) { return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "OU", "UUBL", "(OU)", "UU", "(UU)", "NFE", "LC"]; } - if (isLetsGo) { - return ["Uber", "OU", "UU", "NFE", "LC"]; + if (isLetsGo || isBDSP && !isDoubles) { + return ["Uber", "OU", "UU", "NFE", "LC", "Unreleased"]; } if (isVGC) { return ["Mythical", "Restricted Legendary", "Regular", "NFE", "LC"]; @@ -897,6 +908,16 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable['gen7letsgo'].learnsets[id][moveid] = '7'; } } + const BDSPLearnsets = Dex.mod('gen8bdsp').data.Learnsets; + for (const id in BDSPLearnsets) { + const species = Dex.mod('gen8bdsp').species.get(id); + if (species.isNonstandard && species.isNonstandard !== 'Unobtainable') continue; + const learnset = BDSPLearnsets[id].learnset; + BattleTeambuilderTable['gen8bdsp'].learnsets[id] = {}; + for (const moveid in learnset) { + BattleTeambuilderTable['gen8bdsp'].learnsets[id][moveid] = '8g'; + } + } const DLC1Learnsets = Dex.mod('gen8dlc1').data.Learnsets; for (const id in DLC1Learnsets) { const learnset = DLC1Learnsets[id].learnset; diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index b254fa6518..d8f96881a2 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -24,6 +24,9 @@ if (this.curTeam.format.includes('letsgo')) { this.curTeam.dex = Dex.mod('gen7letsgo'); } + if (this.curTeam.format.includes('bdsp')) { + this.curTeam.dex = Dex.mod('gen8bdsp'); + } Storage.activeSetList = this.curSetList; } }, @@ -685,6 +688,9 @@ if (this.curTeam.format.includes('letsgo')) { this.curTeam.dex = Dex.mod('gen7letsgo'); } + if (this.curTeam.format.includes('bdsp')) { + this.curTeam.dex = Dex.mod('gen8bdsp'); + } Storage.activeSetList = this.curSetList = Storage.unpackTeam(this.curTeam.team); this.curTeamIndex = i; this.update(); @@ -1158,6 +1164,7 @@ renderSet: function (set, i) { var species = this.curTeam.dex.species.get(set.species); var isLetsGo = this.curTeam.format.includes('letsgo'); + var isBDSP = this.curTeam.format.includes('bdsp'); var isNatDex = this.curTeam.format.includes('nationaldex'); var buf = '
  • '; if (!set.species) { @@ -1204,12 +1211,15 @@ buf += '' + (set.shiny ? 'Yes' : 'No') + ''; if (!isLetsGo) { if (this.curTeam.gen === 8 && !isNatDex) { + if (isBDSP && species.baseSpecies === "Unown") { + buf += '' + (set.hpType || 'Dark') + ''; + } // Hidden Power isn't in normal Gen 8 } else { buf += '' + (set.hpType || 'Dark') + ''; } } - if (this.curTeam.gen === 8 && (species.canGigantamax || species.forme === 'Gmax')) { + if (this.curTeam.gen === 8 && !isBDSP && (species.canGigantamax || species.forme === 'Gmax')) { buf += '' + (set.gigantamax || species.forme === 'Gmax' ? 'Yes' : 'No') + ''; } } @@ -1458,6 +1468,9 @@ if (this.curTeam.format.includes('letsgo')) { this.curTeam.dex = Dex.mod('gen7letsgo'); } + if (this.curTeam.format.includes('bdsp')) { + this.curTeam.dex = Dex.mod('gen8bdsp'); + } this.save(); if (this.curTeam.gen === 5 && !Dex.loadedSpriteData['bw']) Dex.loadSpriteData('bw'); this.update(); @@ -2572,6 +2585,7 @@ var buf = ''; var set = this.curSet; var isLetsGo = this.curTeam.format.includes('letsgo'); + var isBDSP = this.curTeam.format.includes('bdsp'); var isNatDex = this.curTeam.gen === 8 && this.curTeam.format.includes('nationaldex'); var species = this.curTeam.dex.species.get(set.species); if (!set) return; @@ -2607,7 +2621,7 @@ buf += ''; buf += '
  • '; - if (species.canGigantamax || species.forme === 'Gmax') { + if (!isBDSP && (species.canGigantamax || species.forme === 'Gmax')) { buf += '
    '; if (species.forme === 'Gmax') { buf += 'Yes'; @@ -2629,7 +2643,7 @@ buf += '
    '; } - if (!isLetsGo && (this.curTeam.gen === 7 || isNatDex)) { + if (!isLetsGo && (this.curTeam.gen === 7 || isNatDex || (isBDSP && species.baseSpecies === 'Unown'))) { buf += '
    Male '; buf += ' '; - if (this.curTeam.format.indexOf('hackmons') < 0) { + if (!this.curTeam.format.includes('hackmons')) { buf += ''; } else { buf += ''; @@ -3220,8 +3220,8 @@ if (set.happiness) delete set.happiness; if (set.shiny) delete set.shiny; if (set.gigantamax) delete set.gigantamax; - if (this.curTeam.format.indexOf('hackmons') < 0) { - set.item = (species.requiredItem || ''); + if (!this.curTeam.format.includes('hackmons') && species.requiredItems.length === 1) { + set.item = species.requiredItems[0]; } else { set.item = ''; } diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index 7f6a562a2c..729951a8a2 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -1355,7 +1355,7 @@ class Species implements Effect { readonly evoMove: string; readonly evoItem: string; readonly evoCondition: string; - readonly requiredItem: string; + readonly requiredItems: ReadonlyArray; readonly tier: string; readonly isTotem: boolean; readonly isMega: boolean; @@ -1404,7 +1404,7 @@ class Species implements Effect { this.evoMove = data.evoMove || ''; this.evoItem = data.evoItem || ''; this.evoCondition = data.evoCondition || ''; - this.requiredItem = data.requiredItem || ''; + this.requiredItems = data.requiredItems || []; this.tier = data.tier || ''; this.isTotem = false; diff --git a/src/battle-dex.ts b/src/battle-dex.ts index cf7e78bc01..d564b70005 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -854,16 +854,16 @@ class ModdedDex { Object.assign(data, table.overrideMoveData[id]); } } + if (this.modid !== `gen${this.gen}`) { + const table = window.BattleTeambuilderTable[this.modid]; + if (id in table.overrideMoveData) { + Object.assign(data, table.overrideMoveData[id]); + } + } if (this.gen <= 3 && data.category !== 'Status') { data.category = Dex.getGen3Category(data.type); } - // For LGPE/BDSP - const table = window.BattleTeambuilderTable[this.modid]; - if (id in table.overrideMoveData) { - Object.assign(data, table.overrideMoveData[id]); - } - const move = new Move(id, name, data); this.cache.Moves[id] = move; return move; @@ -937,6 +937,12 @@ class ModdedDex { Object.assign(data, table.overrideSpeciesData[id]); } } + if (this.modid !== `gen${this.gen}`) { + const table = window.BattleTeambuilderTable[this.modid]; + if (id in table.overrideSpeciesData) { + Object.assign(data, table.overrideSpeciesData[id]); + } + } if (this.gen < 3 || this.modid === 'gen7letsgo') { data.abilities = {0: "No Ability"}; } From 5f09c4b46a6379fcccb6a6d5e7d8a1313a15655f Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 6 Dec 2021 19:58:00 -0500 Subject: [PATCH 241/770] Teambuilder: Fix automatically setting required items (#1906) --- src/battle-dex-data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index 729951a8a2..58ab82ff0f 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -1404,7 +1404,7 @@ class Species implements Effect { this.evoMove = data.evoMove || ''; this.evoItem = data.evoItem || ''; this.evoCondition = data.evoCondition || ''; - this.requiredItems = data.requiredItems || []; + this.requiredItems = data.requiredItems || (data.requiredItem ? [data.requiredItem] : []); this.tier = data.tier || ''; this.isTotem = false; From 5ff827609012a5484994e4a2287e968f0c5f1087 Mon Sep 17 00:00:00 2001 From: missyaria <93721556+missyaria@users.noreply.github.com> Date: Wed, 8 Dec 2021 11:26:59 +0100 Subject: [PATCH 242/770] Separate subroom buttons in roomlist (#1903) --- js/client-rooms.js | 13 +++++++------ style/client.css | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/js/client-rooms.js b/js/client-rooms.js index 87167081e9..ed91f501be 100644 --- a/js/client-rooms.js +++ b/js/client-rooms.js @@ -80,20 +80,21 @@ app.roomsFirstOpen = 2; } }, + renderRoomBtn: function (roomData) { var id = toID(roomData.title); - var buf = '
    (' + Number(roomData.userCount) + ' users) ' + BattleLog.escapeHTML(roomData.title) + '
    ' + BattleLog.escapeHTML(roomData.desc || ''); + var buf = '
    (' + Number(roomData.userCount) + ' users) ' + BattleLog.escapeHTML(roomData.title) + '
    ' + BattleLog.escapeHTML(roomData.desc || '') + '
    '; if (roomData.subRooms && roomData.subRooms.length) { - buf += '
    Subrooms: '; + buf += '
    Subrooms:'; for (var i = 0; i < roomData.subRooms.length; i++) { - if (i) buf += ', '; - buf += ' ' + BattleLog.escapeHTML(roomData.subRooms[i]); + buf += ' ' + BattleLog.escapeHTML(roomData.subRooms[i]) + ''; } - buf += ''; + buf += '
    '; } - buf += '
    '; + buf += '
    '; return buf; }, + compareRooms: function (roomA, roomB) { return roomB.userCount - roomA.userCount; }, diff --git a/style/client.css b/style/client.css index 0d135a95de..5c291e7091 100644 --- a/style/client.css +++ b/style/client.css @@ -1308,6 +1308,20 @@ p.or:after { color: #224466; text-decoration: none; } +.roomlist .subrooms { + font-size: 8pt; + padding-left: 20px; + margin: -5px 0 4px; +} +.roomlist .subrooms i.fa-level-up { + margin-right: 5px; +} +.roomlist .subrooms a.ilink { + display: inline-block; + margin: 0; + vertical-align: middle; + font-size: 8pt; +} /********************************************************* * Chat From 56130457925c46449b31e186175f6dbf050e506e Mon Sep 17 00:00:00 2001 From: missyaria <93721556+missyaria@users.noreply.github.com> Date: Thu, 9 Dec 2021 01:10:55 +0100 Subject: [PATCH 243/770] Make hyperlinks more visible when displayed in /wall (#1907) --- style/client.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/style/client.css b/style/client.css index 5c291e7091..ffddb26924 100644 --- a/style/client.css +++ b/style/client.css @@ -1374,6 +1374,9 @@ p.or:after { font-size: 8pt; color: #888888; } +.chat .message-announce small { + color: #def; +} .chat.timer { color: #992222; } From d281954476471dde2e2f4532e3bfc6a05302b6d6 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 13 Dec 2021 12:00:56 -0500 Subject: [PATCH 244/770] Teambuilder: Fix CAP LC & BDSP Hackmons (#1905) --- src/battle-dex-search.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index f030ad3dca..25748dc072 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -878,12 +878,14 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { table = table['gen' + dex.gen]; } else if (isVGCOrBS) { table = table['gen' + dex.gen + 'vgc']; - } else if (table['gen' + dex.gen + 'doubles'] && dex.gen > 4 && + } else if ( + table['gen' + dex.gen + 'doubles'] && dex.gen > 4 && this.formatType !== 'letsgo' && this.formatType !== 'bdspdoubles' && this.formatType !== 'dlc1doubles' && ( - format.includes('doubles') || format.includes('triples') || format.endsWith('lc') || - format.endsWith('lcuu') || format === 'freeforall' || format.startsWith('ffa') - )) { + format.includes('doubles') || format.includes('triples') || + format === 'freeforall' || format.startsWith('ffa') + ) + ) { table = table['gen' + dex.gen + 'doubles']; isDoublesOrBS = true; } else if (dex.gen < 8 && !this.formatType) { @@ -934,11 +936,12 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { else if (format === 'pu') tierSet = tierSet.slice(slices.PU || slices.NU); else if (format === 'zu') tierSet = tierSet.slice(slices.ZU || slices.PU || slices.NU); else if (format === 'lc' || format === 'lcuu' || format.startsWith('lc') || (format !== 'caplc' && format.endsWith('lc'))) tierSet = tierSet.slice(slices.LC); - else if (format === 'cap') tierSet = tierSet.slice(0, slices.Uber).concat(tierSet.slice(slices.OU)); - else if (format === 'caplc') tierSet = tierSet.slice(slices['CAP LC'], slices.Uber).concat(tierSet.slice(slices.LC)); - else if (format === 'anythinggoes' || format.endsWith('ag') || format.startsWith('ag')) { + else if (format === 'cap') tierSet = tierSet.slice(0, slices.AG || slices.Uber).concat(tierSet.slice(slices.OU)); + else if (format === 'caplc') { + tierSet = tierSet.slice(slices['CAP LC'], slices.AG || slices.Uber).concat(tierSet.slice(slices.LC)); + } else if (format === 'anythinggoes' || format.endsWith('ag') || format.startsWith('ag')) { tierSet = tierSet.slice(slices.AG); - } else if (format.includes('hackmons') || format.endsWith('bh')) tierSet = tierSet.slice(slices.AG); + } else if (format.includes('hackmons') || format.endsWith('bh')) tierSet = tierSet.slice(slices.AG || slices.Uber); else if (format === 'monotype') tierSet = tierSet.slice(slices.Uber); else if (format === 'doublesubers') tierSet = tierSet.slice(slices.DUber); else if (format === 'doublesou' && dex.gen > 4) tierSet = tierSet.slice(slices.DOU); From 0d1baef5778700a22872a2f58df86e4192009af2 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 13 Dec 2021 22:04:17 -0500 Subject: [PATCH 245/770] Fix /clearignore (#1895) --- js/client-chat.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/js/client-chat.js b/js/client-chat.js index 63c7b2d51f..d4c8f90acd 100644 --- a/js/client-chat.js +++ b/js/client-chat.js @@ -611,10 +611,6 @@ case 'clearignore': if (this.checkBroadcast(cmd, text)) return false; - if (!target) { - this.parseCommand('/help ignore'); - return false; - } if (toID(target) !== 'confirm') { this.add("Are you sure you want to clear your ignore list?"); this.add('|html|If you\'re sure, use /clearignore confirm'); From ecec86dd61ac03a7f8f5dba04fef15297d675e84 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Tue, 14 Dec 2021 10:34:48 -0500 Subject: [PATCH 246/770] FAQ: Update for friends list Closes #1856 --- website/pages/faq-es.md | 2 +- website/pages/faq-it.md | 2 +- website/pages/faq-pt.md | 2 +- website/pages/faq.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/website/pages/faq-es.md b/website/pages/faq-es.md index f06ef55799..7fd06d9687 100644 --- a/website/pages/faq-es.md +++ b/website/pages/faq-es.md @@ -79,7 +79,7 @@ Los equipos se guardan en tus cookies. Por ende, si las borras tus equipos se va ### ¿Cómo agrego a un amigo? -Actualmente PS! no cuenta con un sistema de amigos; sin embargo, hay uno planeado. +Escribe `/friend add (nombre)` para agregar amigos. Puedes ver tu lista de amigos con el comando `/friends`. ### ¿Por qué se reinició el servidor? diff --git a/website/pages/faq-it.md b/website/pages/faq-it.md index bd4d0c2095..734035131a 100644 --- a/website/pages/faq-it.md +++ b/website/pages/faq-it.md @@ -79,7 +79,7 @@ I team sono salvati utilizzando i cookie. Se rimuovi i cookie, anche i tuoi team ### Come posso aggiungere un amico? -Al momento, PS! non dispone di una funzione per aggiungere gli amici; tuttavia, è in programma. +Scrivi `/friend add (nome)` per aggiungere amici. Puoi visualizzare la tua lista di amici con il comando `/friends`. ### Come mai il server è stato riavviato? diff --git a/website/pages/faq-pt.md b/website/pages/faq-pt.md index 45ac171df2..044fb509d1 100644 --- a/website/pages/faq-pt.md +++ b/website/pages/faq-pt.md @@ -79,7 +79,7 @@ Times são salvos usando os cookies. Se você limpar seus cookies, seus times s ### Como adiciono meu amigo? -Por enquanto o PS! não tem um sistema de amizades; no entanto, ter um é planejado. +Digite `/friend add (nome)` para adicionar amigos. Você pode ver sua lista de amigos com o comando `/friends`. ### Por que o servidor reiniciou? diff --git a/website/pages/faq.md b/website/pages/faq.md index f7a0527fef..44e6d2f420 100644 --- a/website/pages/faq.md +++ b/website/pages/faq.md @@ -79,7 +79,7 @@ Teams are saved using your cookies. If you clear your cookies, you clear your te ### How do I add my friend? -Currently PS! does not have a friends system; however, one is planned. +Type `/friend add (name)` to add friends. You can view your list of friends with the command `/friends`. ### Why did the server restart? From abb724d452bf35aa51b48cafa1b6f111ef5970cf Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sat, 18 Dec 2021 12:44:14 -0700 Subject: [PATCH 247/770] Add CAP 30 sprite indexes (#1904) --- src/battle-dex-data.ts | 2 ++ src/battle-dex.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index 58ab82ff0f..729477635a 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -481,6 +481,8 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { astrolotl: 1308 + 29, miasmaw: 1308 + 30, chromera: 1308 + 31, + venomicon: 1308 + 32, + venomiconepilogue: 1308 + 33, syclar: 1344 + 0, embirch: 1344 + 1, diff --git a/src/battle-dex.ts b/src/battle-dex.ts index d564b70005..84a674f46d 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -719,7 +719,7 @@ const Dex = new class implements ModdedDex { let top = Math.floor(num / 12) * 30; let left = (num % 12) * 40; let fainted = ((pokemon as Pokemon | ServerPokemon)?.fainted ? `;opacity:.3;filter:grayscale(100%) brightness(.5)` : ``); - return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v6) no-repeat scroll -${left}px -${top}px${fainted}`; + return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v7) no-repeat scroll -${left}px -${top}px${fainted}`; } getTeambuilderSpriteData(pokemon: any, gen: number = 0): TeambuilderSpriteData { From d9a956e407fc8353230bee4f7e740bb72d2d88c3 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 25 Dec 2021 01:59:41 -0500 Subject: [PATCH 248/770] Refactor Ability data overriding (#1908) --- build-tools/build-indexes | 52 +++++++++++++++++++++++++++------------ src/battle-dex.ts | 15 +++++++---- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 42f5dd3670..31bae142c1 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -965,6 +965,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); // Client relevant data that should be overriden by past gens and mods const overrideSpeciesKeys = ['abilities', 'baseStats', 'cosmeticFormes', 'requiredItems', 'types', 'unreleasedHidden']; const overrideMoveKeys = ['accuracy', 'basePower', 'category', 'desc', 'flags', 'isNonstandard', 'pp', 'priority', 'shortDesc', 'target', 'type']; + const overrideAbilityKeys = ['desc', 'isNonstandard', 'rating', 'shortDesc']; // // Past gen table @@ -973,8 +974,11 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); for (const genNum of [7, 6, 5, 4, 3, 2, 1]) { const gen = 'gen' + genNum; const nextGen = 'gen' + (genNum + 1); - const genData = Dex.mod(gen).data; - const nextGenData = Dex.mod(nextGen).data; + const genDex = Dex.mod(gen); + const genData = genDex.data; + const nextGenDex = Dex.mod(nextGen); + const nextGenData = nextGenDex.data; + const overrideSpeciesData = {}; BattleTeambuilderTable[gen].overrideSpeciesData = overrideSpeciesData; for (const id in genData.Pokedex) { @@ -991,8 +995,8 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const overrideMoveData = {}; BattleTeambuilderTable[gen].overrideMoveData = overrideMoveData; for (const id in genData.Moves) { - const curEntry = Dex.mod(gen).moves.get(id); - const nextEntry = Dex.mod(nextGen).moves.get(id); + const curEntry = genDex.moves.get(id); + const nextEntry = nextGenDex.moves.get(id); for (const key of overrideMoveKeys) { if (key === 'category' && genNum <= 3) continue; if (JSON.stringify(curEntry[key]) !== JSON.stringify(nextEntry[key])) { @@ -1002,26 +1006,29 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } } + const overrideAbilityData = {}; + BattleTeambuilderTable[gen].overrideAbilityData = overrideAbilityData; + for (const id in genData.Abilities) { + const curEntry = genDex.abilities.get(id); + const nextEntry = nextGenDex.abilities.get(id); + for (const key of overrideAbilityKeys) { + if (JSON.stringify(curEntry[key]) !== JSON.stringify(nextEntry[key])) { + if (!overrideAbilityData[id]) overrideAbilityData[id] = {}; + overrideAbilityData[id][key] = curEntry[key]; + } + } + } + const overrideItemDesc = {}; BattleTeambuilderTable[gen].overrideItemDesc = overrideItemDesc; for (const id in genData.Items) { - const curEntry = Dex.mod(gen).items.get(id); - const nextEntry = Dex.mod(nextGen).items.get(id); + const curEntry = genDex.items.get(id); + const nextEntry = nextGenDex.items.get(id); if ((curEntry.shortDesc || curEntry.desc) !== (nextEntry.shortDesc || nextEntry.desc)) { overrideItemDesc[id] = (curEntry.shortDesc || curEntry.desc); } } - const overrideAbilityDesc = {}; - BattleTeambuilderTable[gen].overrideAbilityDesc = overrideAbilityDesc; - for (const id in genData.Abilities) { - const curEntry = Dex.mod(gen).abilities.get(id); - const nextEntry = Dex.mod(nextGen).abilities.get(id); - if ((curEntry.shortDesc || curEntry.desc) !== (nextEntry.shortDesc || nextEntry.desc)) { - overrideAbilityDesc[id] = (curEntry.shortDesc || curEntry.desc); - } - } - const overrideTypeChart = {}; BattleTeambuilderTable[gen].overrideTypeChart = overrideTypeChart; const removeType = {}; @@ -1075,6 +1082,19 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } } } + + const overrideAbilityData = {}; + BattleTeambuilderTable[mod].overrideAbilityData = overrideAbilityData; + for (const id in modData.Abilities) { + const modEntry = modDex.abilities.get(id); + const parentEntry = parentDex.abilities.get(id); + for (const key of overrideAbilityKeys) { + if (JSON.stringify(modEntry[key]) !== JSON.stringify(parentEntry[key])) { + if (!overrideAbilityData[id]) overrideAbilityData[id] = {}; + overrideAbilityData[id][key] = modEntry[key]; + } + } + } } buf += `exports.BattleTeambuilderTable = JSON.parse('${JSON.stringify(BattleTeambuilderTable).replace(/['\\]/g, "\\$&")}');\n\n`; diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 84a674f46d..5fd9dca370 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -906,11 +906,16 @@ class ModdedDex { let data = {...Dex.abilities.get(name)}; - for (let i = this.gen; i < 8; i++) { - const table = window.BattleTeambuilderTable['gen' + i]; - if (id in table.overrideAbilityDesc) { - data.shortDesc = table.overrideAbilityDesc[id]; - break; + for (let i = Dex.gen - 1; i >= this.gen; i--) { + const table = window.BattleTeambuilderTable[`gen${i}`]; + if (id in table.overrideAbilityData) { + Object.assign(data, table.overrideAbilityData[id]); + } + } + if (this.modid !== `gen${this.gen}`) { + const table = window.BattleTeambuilderTable[this.modid]; + if (id in table.overrideAbilityData) { + Object.assign(data, table.overrideAbilityData[id]); } } From 0291b2dacb99ed29630dee6651eaff0975b71475 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Mon, 27 Dec 2021 15:48:49 -0600 Subject: [PATCH 249/770] Fix PP tracking for Metronome vs. Pressure (#1910) --- src/battle-dex-data.ts | 2 ++ src/battle.ts | 44 +++++++++++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index 729477635a..6daa76ef59 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -1114,6 +1114,7 @@ class Move implements Effect { readonly category: 'Physical' | 'Special' | 'Status'; readonly priority: number; readonly target: MoveTarget; + readonly pressureTarget: MoveTarget; readonly flags: Readonly; readonly critRatio: number; @@ -1153,6 +1154,7 @@ class Move implements Effect { this.category = data.category || 'Physical'; this.priority = data.priority || 0; this.target = data.target || 'normal'; + this.pressureTarget = data.pressureTarget || this.target; this.flags = data.flags || {}; this.critRatio = data.critRatio === 0 ? 0 : (data.critRatio || 1); diff --git a/src/battle.ts b/src/battle.ts index ca052287cf..2bce716186 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1409,33 +1409,41 @@ export class Battle { this.scene.updateStatbar(pokemon); if (fromeffect.id === 'sleeptalk') { pokemon.rememberMove(move.name, 0); - } else if (!fromeffect.id || fromeffect.id === 'pursuit') { + } + let callerMoveForPressure = null; + // will not include effects that are conditions named after moves like Magic Coat and Snatch, which is good + if (fromeffect.id && kwArgs.from.startsWith("move:")) { + callerMoveForPressure = fromeffect as Move; + } + if (!fromeffect.id || callerMoveForPressure || fromeffect.id === 'pursuit') { let moveName = move.name; - if (move.isZ) { - pokemon.item = move.isZ; - let item = Dex.items.get(move.isZ); - if (item.zMoveFrom) moveName = item.zMoveFrom; - } else if (move.name.slice(0, 2) === 'Z-') { - moveName = moveName.slice(2); - move = Dex.moves.get(moveName); - if (window.BattleItems) { - for (let item in BattleItems) { - if (BattleItems[item].zMoveType === move.type) pokemon.item = item; + if (!callerMoveForPressure) { + if (move.isZ) { + pokemon.item = move.isZ; + let item = Dex.items.get(move.isZ); + if (item.zMoveFrom) moveName = item.zMoveFrom; + } else if (move.name.slice(0, 2) === 'Z-') { + moveName = moveName.slice(2); + move = Dex.moves.get(moveName); + if (window.BattleItems) { + for (let item in BattleItems) { + if (BattleItems[item].zMoveType === move.type) pokemon.item = item; + } } } } let pp = 1; - // Sticky Web is never affected by pressure - if (this.abilityActive(['Pressure']) && move.id !== 'stickyweb') { + if (this.abilityActive(['Pressure'])) { const foeTargets = []; + const moveTarget = move.pressureTarget; if ( !target && this.gameType === 'singles' && - !['self', 'allies', 'allySide', 'adjacentAlly', 'adjacentAllyOrSelf', 'allyTeam'].includes(move.target) + !['self', 'allies', 'allySide', 'adjacentAlly', 'adjacentAllyOrSelf', 'allyTeam'].includes(moveTarget) ) { // Hardcode for moves without a target in singles foeTargets.push(pokemon.side.foe.active[0]); - } else if (['all', 'allAdjacent', 'allAdjacentFoes', 'foeSide'].includes(move.target)) { + } else if (['all', 'allAdjacent', 'allAdjacentFoes', 'foeSide'].includes(moveTarget)) { // We loop through all sides here for FFA for (const side of this.sides) { if (side === pokemon.side || side === pokemon.side.ally) continue; @@ -1453,7 +1461,11 @@ export class Battle { } } } - pokemon.rememberMove(moveName, pp); + if (!callerMoveForPressure) { + pokemon.rememberMove(moveName, pp); + } else { + pokemon.rememberMove(callerMoveForPressure.name, pp - 1); // 1 pp was already deducted from using the move itself + } } pokemon.lastMove = move.id; this.lastMove = move.id; From a583e3e06f2f09bf1ee8ce41971ef57b59defd0a Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sat, 1 Jan 2022 14:34:54 -0700 Subject: [PATCH 250/770] Add RU to the BDSP teambuilder (#1913) --- build-tools/build-indexes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 31bae142c1..03d1f1d722 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -560,7 +560,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); return ["Uber", "OU", "UU", "NFE", "LC"]; } if (isBDSP && !isDoubles) { - return ["CAP", "CAP NFE", "CAP LC", "Uber", "OU", "UUBL", "UU", "(UU)", "NFE", "LC", "Unreleased"]; + return ["CAP", "CAP NFE", "CAP LC", "Uber", "OU", "UUBL", "UU", "RUBL", "RU", "NFE", "LC", "Unreleased"]; } if (isVGC) { return ["Mythical", "Restricted Legendary", "Regular", "NFE", "LC"]; From 40b2814999dea9f289115b9cd7b5383cd0aca6a8 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 1 Jan 2022 18:14:07 -0500 Subject: [PATCH 251/770] Tooltips: Fix ability stat boosts showing when Ngas is active (#1912) --- src/battle-tooltips.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 755a56179d..7e9abe5167 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -982,7 +982,7 @@ class BattleTooltips { } const ability = toID( - clientPokemon?.effectiveAbility(serverPokemon) || serverPokemon.ability || serverPokemon.baseAbility + clientPokemon?.effectiveAbility(serverPokemon) ?? (serverPokemon.ability || serverPokemon.baseAbility) ); // check for burn, paralysis, guts, quick feet From 5c4179bacf968138e6f81372ececb4f00d12f24a Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 1 Jan 2022 18:14:29 -0500 Subject: [PATCH 252/770] Teambuilder: Show Restricted Legendaries for VGC 2022 (#1914) --- src/battle-dex-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 25748dc072..d31acd0252 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -923,7 +923,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { else if (isVGCOrBS) { if ( format === 'vgc2010' || format === 'vgc2016' || format.startsWith('vgc2019') || - format.endsWith('series10') || format.endsWith('series11') + format === 'vgc2022' || format.endsWith('series10') || format.endsWith('series11') ) { tierSet = tierSet.slice(slices["Restricted Legendary"]); } else { From dbeed12ee66a501d9e04f0bf551706762cb585c1 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Mon, 3 Jan 2022 15:14:38 -0500 Subject: [PATCH 253/770] Pages: Update proxy help --- website/pages/proxyhelp.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/pages/proxyhelp.md b/website/pages/proxyhelp.md index aa98b05f06..c696a1b28f 100644 --- a/website/pages/proxyhelp.md +++ b/website/pages/proxyhelp.md @@ -5,11 +5,11 @@ If you received the above message and are unable to chat, you are using a [proxy](https://simple.wikipedia.org/wiki/Proxy_server) or [VPN](https://simple.wikipedia.org/wiki/Virtual_private_network) connection. Here are some troubleshooting steps you can take to resolve this issue - after each step make sure to type `/logout` in any chatroom (such as Lobby) and log back in. - Turn your proxy or VPN off. - Make sure you are logged out on all other devices. -- If you are using the desktop client, try using the [web client](https://play.pokemonshowdown.com/) instead. +- If you are using the Opera, Puffin, or Brave browsers, you may have a VPN enabled by default. Try using a different browser such as Chrome, Firefox, or Safari. +- iCloud Private Relay is considered a proxy connection. Please disable it if you have it enabled on your device. - If you are using TOR, close it and open Showdown in a standard browser. -- If you are using the Opera browser, you may have a VPN enabled by default. Try using a different browser such as Chrome, Firefox, or Safari. - If you are using a shared or commercial network, it may have a proxy or VPN enabled. Either wait until you can connect on your usual network or contact your system administrator. - If you are using a school or work-issued device, it may have proxy or VPN software enabled. Use a different device or contact your system administrator. - Type `/ip` in any chatroom. You will see your IP (it will be 4 numbers separated by periods such as `123.456.78.910`). Check your IP with a website such as [WhatIsMyIPAddress](https://whatismyipaddress.com/) or [IPLocationTools](https://www.iplocationtools.com/). If the geolocation or Internet service provider indicated is not familiar, you are using a proxy or VPN connection. If this is your home connection, you can edit your network configuration if you have the knowledge to do so. Otherwise contact your Internet service provider for assistance. -Still locked and you're completely certain that you are not on a proxy or VPN connection? File a Help Ticket on Showdown by typing `/ht` in any chatroom or directly at https://play.pokemonshowdown.com/view-help-request and global staff will assist you. \ No newline at end of file +Still locked and you're completely certain that you are not on a proxy or VPN connection? File a Help Ticket on Showdown by typing `/ht` in any chatroom or directly at https://play.pokemonshowdown.com/view-help-request and global staff will assist you. From fd20697389ea230c17384a25099467e20921978b Mon Sep 17 00:00:00 2001 From: Quanyails Date: Mon, 3 Jan 2022 20:55:00 -0500 Subject: [PATCH 254/770] Write learnsets to JSON (#1911) --- build-tools/build-indexes | 1 + 1 file changed, 1 insertion(+) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 03d1f1d722..b551ee8faf 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -1225,6 +1225,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j const Learnsets = requireNoCache('../data/pokemon-showdown/.data-dist/learnsets.js').Learnsets; const buf = 'exports.BattleLearnsets = ' + es3stringify(Learnsets) + ';'; fs.writeFileSync('data/learnsets.js', buf); + fs.writeFileSync('data/learnsets.json', JSON.stringify(Learnsets)); } /********************************************************* From c785df1b52ab5a806a781763ffb3c5de33375f37 Mon Sep 17 00:00:00 2001 From: Nol <54009001+Nolnis@users.noreply.github.com> Date: Sat, 8 Jan 2022 16:06:00 -0500 Subject: [PATCH 255/770] Rules: Correct French translation (#1918) --- website/pages/rules-fr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/rules-fr.md b/website/pages/rules-fr.md index 764f40a493..ed64cbb76a 100755 --- a/website/pages/rules-fr.md +++ b/website/pages/rules-fr.md @@ -22,7 +22,7 @@ 2. **Pas de spam, de troll, ou d'agressivité**. Cela inclut également faire de la publicité, raid et flood le chat. Écrire tout en MAJUSCULES ou __formater__ son texte est accepté pour mettre de l'emphase, mais ne doit pas être utilisé en continu. Cette règle s'applique également aux messages privés. -3. **Pas de minimod**. Ne tentez pas de modérer si ce n'est pas votre rôle. Ne disez pas à des personnes qu'elles vont être mute, ne demandez pas à ce que des personnes soient mute, et ne discutez pas de si une personne devrait ou ne devrait pas être mute ("inb4 mute" etc). Cela s'applique aux bans et autres punitions. +3. **Pas de minimod**. Ne tentez pas de modérer si ce n'est pas votre rôle. Ne dites pas à des personnes qu'elles vont être mute, ne demandez pas à ce que des personnes soient mute, et ne discutez pas de si une personne devrait ou ne devrait pas être mute ("inb4 mute" etc). Cela s'applique aux bans et autres punitions. 4. **Arrêtez de débattre des règles quand on vous le demande.** Vous pouvez en parler la plupart du temps, mais si les modérateurs vous demandent d'arrêter, faites-le s'il vous plaît. From 3339b80c7b58657a81f6078206e6d7fabe07b372 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Tue, 11 Jan 2022 08:42:58 -0700 Subject: [PATCH 256/770] BW PU/ZU: Add teambuilder support (#1920) --- build-tools/build-indexes | 24 ++++++++++-------------- src/battle-dex-search.ts | 27 ++++++++++++++------------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index b551ee8faf..310511a3f5 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -456,23 +456,21 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); (gen === 'gen8' && id === 'ferroseed') || (gen === 'gen7' && id === 'ferroseed') || (gen === 'gen6' && ['ferroseed', 'pawniard', 'vullaby'].includes(id)) || - (gen === 'gen5' && id === 'ferroseed') || + (gen === 'gen5' && ['bronzor', 'dwebble', 'ferroseed', 'natu', 'riolu', 'tentacool'].includes(id)) || (gen === 'gen4' && ['clamperl', 'diglett', 'gligar', 'hippopotas', 'snover', 'wynaut'].includes(id)) ) ) { if (!tierTable['LC']) tierTable['LC'] = []; tierTable['LC'].push(id); } - - if (genNum >= 7) { - const format = Dex.formats.get(gen + 'zu'); - if (Dex.formats.getRuleTable(format).isBannedSpecies(species) && ["(PU)", "NFE", "LC"].includes(species.tier)) { + if (genNum >= 5) { + const zu = Dex.formats.get(gen + 'zu'); + if (zu.exists && Dex.formats.getRuleTable(zu).isBannedSpecies(species) && + ["(PU)", "NFE", "LC"].includes(species.tier)) { zuBans[species.id] = 1; } - } - if (genNum >= 5) { - const format = Dex.formats.get(gen + (isNatDex ? 'nationaldex' : '') + 'monotype'); - if (Dex.formats.getRuleTable(format).isBannedSpecies(species)) { + const mono = Dex.formats.get(gen + (isNatDex ? 'nationaldex' : '') + 'monotype'); + if (Dex.formats.getRuleTable(mono).isBannedSpecies(species)) { monotypeBans[species.id] = 1; } } @@ -540,10 +538,8 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable[gen].tiers = tiers; BattleTeambuilderTable[gen].items = items; BattleTeambuilderTable[gen].formatSlices = formatSlices; - if (genNum >= 7) { - BattleTeambuilderTable[gen].zuBans = zuBans; - } if (genNum >= 5) { + BattleTeambuilderTable[gen].zuBans = zuBans; BattleTeambuilderTable[gen].monotypeBans = monotypeBans; } if (isDLC1) { @@ -560,7 +556,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); return ["Uber", "OU", "UU", "NFE", "LC"]; } if (isBDSP && !isDoubles) { - return ["CAP", "CAP NFE", "CAP LC", "Uber", "OU", "UUBL", "UU", "RUBL", "RU", "NFE", "LC", "Unreleased"]; + return ["CAP", "CAP NFE", "CAP LC", "Uber", "(Uber)", "OU", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "NFE", "LC", "Unreleased"]; } if (isVGC) { return ["Mythical", "Restricted Legendary", "Regular", "NFE", "LC"]; @@ -575,7 +571,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "OU", "(OU)", "UUBL", "UU", "NUBL", "NU", "NFE", "LC"]; } if (gen === 'gen5') { - return ["CAP", "CAP NFE", "CAP LC", "Uber", "OU", "(OU)", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "(NU)", "NFE", "LC"]; + return ["CAP", "CAP NFE", "CAP LC", "Uber", "OU", "(OU)", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "PUBL", "PU", "(PU)", "NFE", "LC"]; } if (gen === 'gen7') { return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "OU", "(OU)", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "PUBL", "PU", "(PU)", "NFE", "LC", "Unreleased"]; diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index d31acd0252..1229fd5e6f 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -932,7 +932,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { } else if (format === 'ou') tierSet = tierSet.slice(slices.OU); else if (format === 'uu') tierSet = tierSet.slice(slices.UU); else if (format === 'ru') tierSet = tierSet.slice(slices.RU || slices.UU); - else if (format === 'nu') tierSet = tierSet.slice(slices.NU || slices.UU); + else if (format === 'nu') tierSet = tierSet.slice(slices.NU || slices.RU || slices.UU); else if (format === 'pu') tierSet = tierSet.slice(slices.PU || slices.NU); else if (format === 'zu') tierSet = tierSet.slice(slices.ZU || slices.PU || slices.NU); else if (format === 'lc' || format === 'lcuu' || format.startsWith('lc') || (format !== 'caplc' && format.endsWith('lc'))) tierSet = tierSet.slice(slices.LC); @@ -964,18 +964,19 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { ]; } - if (format === 'zu' && dex.gen >= 7) { - tierSet = tierSet.filter(([type, id]) => { - if (id in table.zuBans) return false; - return true; - }); - } - - if (format === 'monotype' && dex.gen >= 5 && table.monotypeBans) { - tierSet = tierSet.filter(([type, id]) => { - if (id in table.monotypeBans) return false; - return true; - }); + if (dex.gen >= 5) { + if (format === 'zu' && table.zuBans) { + tierSet = tierSet.filter(([type, id]) => { + if (id in table.zuBans) return false; + return true; + }); + } + if (format === 'monotype' && table.monotypeBans) { + tierSet = tierSet.filter(([type, id]) => { + if (id in table.monotypeBans) return false; + return true; + }); + } } // Filter out Gmax Pokemon from standard tier selection From 83feec1be1be20d53c3cc64e17f574834397c2f0 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Sat, 29 Jan 2022 16:14:45 -0500 Subject: [PATCH 257/770] Teambuilder: Fix Alolan Sandshrew listing for LC --- build-tools/build-indexes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 310511a3f5..afdabd2a7e 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -453,7 +453,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if ( tier !== 'LC' && ( - (gen === 'gen8' && id === 'ferroseed') || + (gen === 'gen8' && ['ferroseed', 'sandshrewalola'].includes(id)) || (gen === 'gen7' && id === 'ferroseed') || (gen === 'gen6' && ['ferroseed', 'pawniard', 'vullaby'].includes(id)) || (gen === 'gen5' && ['bronzor', 'dwebble', 'ferroseed', 'natu', 'riolu', 'tentacool'].includes(id)) || From 623a2902d0e4c352e68d550c0af2642bea2b2425 Mon Sep 17 00:00:00 2001 From: Spandan Punwatkar Date: Sun, 30 Jan 2022 04:24:11 +0530 Subject: [PATCH 258/770] Add a team counter for folders (#1928) --- js/client-teambuilder.js | 7 +++++-- src/panel-teambuilder.tsx | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 4ba04e6883..a10aa12fa3 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -347,7 +347,7 @@ buf += '

    Hi

    '; buf += '

    Did you have a good day?

    '; buf += '

    '; - buf += '

    All teams

    '; + buf += '

    All teams (' + teams.length + ')

    '; } else { if (this.curFolder.slice(-1) === '/') { filterFolder = this.curFolder.slice(0, -1); @@ -358,7 +358,10 @@ } } else { filterFormat = this.curFolder; - buf += '

    ' + filterFormat + '

    '; + var func = function (team) { + return team.format === filterFormat; + }; + buf += '

    ' + filterFormat + ' (' + teams.filter(func).length + ')

    '; } } diff --git a/src/panel-teambuilder.tsx b/src/panel-teambuilder.tsx index e714b43a6c..ea1a119abb 100644 --- a/src/panel-teambuilder.tsx +++ b/src/panel-teambuilder.tsx @@ -234,9 +234,9 @@ class TeambuilderPanel extends PSRoomPanel { : filterFolder === '' ?

    Teams not in any folders

    : filterFormat ? -

    {filterFormat}

    +

    {filterFormat} ({teams.length})

    : -

    All Teams

    +

    All Teams ({teams.length})

    }

    From 916f190bf4f5142a305a02dc05115edfe95f2d8a Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 29 Jan 2022 17:55:36 -0500 Subject: [PATCH 259/770] Teambuilder: Show gen 5 sprites when old graphics are preferred (#1924) --- src/battle-dex.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 5fd9dca370..21a8628ecb 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -738,6 +738,7 @@ const Dex = new class implements ModdedDex { }; if (pokemon.shiny) spriteData.shiny = true; if (Dex.prefs('nopastgens')) gen = 6; + if (Dex.prefs('bwgfx') && gen > 5) gen = 5; let xydexExists = (!species.isNonstandard || species.isNonstandard === 'Past' || species.isNonstandard === 'CAP') || [ "pikachustarter", "eeveestarter", "meltan", "melmetal", "pokestarufo", "pokestarufo2", "pokestarbrycenman", "pokestarmt", "pokestarmt2", "pokestargiant", "pokestarhumanoid", "pokestarmonster", "pokestarf00", "pokestarf002", "pokestarspirit", ].includes(species.id); From 2b655fb509feab0e8a151dfe51380d35b1fec6dd Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 29 Jan 2022 18:20:10 -0500 Subject: [PATCH 260/770] Tooltips: Fix small display issue in Gen 2 (#1933) --- src/battle-tooltips.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 7e9abe5167..99d4212366 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -864,14 +864,16 @@ class BattleTooltips { if (item) itemText = 'Item: ' + item + itemEffect; } - text += '

    '; - text += abilityText; - if (itemText) { - // ability/item on one line for your own switch tooltips, two lines everywhere else - text += (!isActive && serverPokemon ? ' / ' : '

    '); + if (abilityText || itemText) { + text += '

    '; + text += abilityText; + if (abilityText && itemText) { + // ability/item on one line for your own switch tooltips, two lines everywhere else + text += (!isActive && serverPokemon ? ' / ' : '

    '); + } text += itemText; + text += '

    '; } - text += '

    '; text += this.renderStats(clientPokemon, serverPokemon, !isActive); From 79a75a722f289e970a542524e1a013cb5e44d6cc Mon Sep 17 00:00:00 2001 From: Leonard Craft III Date: Sat, 29 Jan 2022 17:20:41 -0600 Subject: [PATCH 261/770] Prevent setting timer after a game has ended (#1932) --- js/client-battle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-battle.js b/js/client-battle.js index dd6dddfb10..47cd12f4d0 100644 --- a/js/client-battle.js +++ b/js/client-battle.js @@ -1002,7 +1002,7 @@ return; } - if (!this.autoTimerActivated && Storage.prefs('autotimer')) { + if (!this.autoTimerActivated && Storage.prefs('autotimer') && !this.battle.ended) { this.setTimer('on'); this.autoTimerActivated = true; } From 0e7377b1d312ba6e0989635f1575a8fa69c00075 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 29 Jan 2022 18:28:47 -0500 Subject: [PATCH 262/770] Add confirmation popup when dragging in image (#1917) --- js/client-topbar.js | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/js/client-topbar.js b/js/client-topbar.js index ee4a435abc..713bfa2109 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -805,23 +805,39 @@ CustomBackgroundPopup.readFile = function (file, popup) { var reader = new FileReader(); reader.onload = function (e) { - var noSave = false; if (String(e.target.result).length > 4200000) { if (popup) { $('.bgstatus').html('Image is too large and can\'t be saved. It should be under 3.5MB or so.'); } else { app.addPopupMessage("Image is too large and can't be saved. It should be under 3.5MB or so."); } - noSave = true; } else if (popup) { $('.bgstatus').html('Saved'); popup.$('.cur').removeClass('cur'); + Storage.bg.set(e.target.result, 'custom'); + } else { + app.addPopup(ConfirmBackgroundPopup, {bgUrl: e.target.result}); } - Storage.bg.set(e.target.result, 'custom', noSave); }; reader.readAsDataURL(file); }; + var ConfirmBackgroundPopup = this.ConfirmBackgroundPopup = Popup.extend({ + initialize: function (data) { + var buf = '
    '; + buf += '

    '; + buf += '

    '; + buf += '

    '; + + this.$el.css('max-width', 485).html(buf); + this.$el.html(buf); + }, + setBg: function (bgUrl) { + this.close(); + Storage.bg.set(bgUrl, 'custom'); + } + }); + var LoginPopup = this.LoginPopup = Popup.extend({ type: 'semimodal', initialize: function (data) { From 0191028990153866f84e466b5518d385ef184213 Mon Sep 17 00:00:00 2001 From: Dirain1700 <86363603+Dirain1700@users.noreply.github.com> Date: Sun, 30 Jan 2022 08:57:15 +0900 Subject: [PATCH 263/770] Pages: Update Proxy-ja help (#1919) --- website/pages/faq-ja.md | 2 +- website/pages/proxyhelp-ja.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/website/pages/faq-ja.md b/website/pages/faq-ja.md index eeea053037..49b9d66796 100644 --- a/website/pages/faq-ja.md +++ b/website/pages/faq-ja.md @@ -171,4 +171,4 @@ Endless Battleとは、その名の通り、終わりのない戦いのことで `/rank`を入力すると、"Reset W/L"というボタンが表示されます。このボタンをクリックすると、勝敗をリセットすることができます。なお、他のランキングには影響がなく、勝敗の比率だけが変わります。他のランキングを変更するには、新しいアカウントでやり直してください。 -(originally by [Relados](https://www.smogon.com/forums/members/relados.148715/) and [Zarel](https://www.smogon.com/forums/members/zarel.102803/); updated by [Blitzamirin](https://www.smogon.com/forums/members/blitzamirin.101585/), [Kalalokki](https://www.smogon.com/forums/members/kalalokki.199661/), Kasumi, [shnen](https://www.smogon.com/forums/members/shnen.107178/), Sobi, [Finland](https://www.smogon.com/forums/members/finland.517429/), [Vacate](https://www.smogon.com/forums/members/vacate.189371/), [verbatim](https://www.smogon.com/forums/members/verbatim.93103/), [Zodiax](https://www.smogon.com/forums/members/zodiax.202547/), and [Iyarito](https://www.smogon.com/forums/members/iyarito.219578/); converted to Markdown for the PS! website by [Annika](https://www.smogon.com/forums/members/annika.434112/); translated into Japanese by [Dirain1200](https://www.smogon.com/forums/members/dirain1200.558165/about)) +(originally by [Relados](https://www.smogon.com/forums/members/relados.148715/) and [Zarel](https://www.smogon.com/forums/members/zarel.102803/); updated by [Blitzamirin](https://www.smogon.com/forums/members/blitzamirin.101585/), [Kalalokki](https://www.smogon.com/forums/members/kalalokki.199661/), Kasumi, [shnen](https://www.smogon.com/forums/members/shnen.107178/), Sobi, [Finland](https://www.smogon.com/forums/members/finland.517429/), [Vacate](https://www.smogon.com/forums/members/vacate.189371/), [verbatim](https://www.smogon.com/forums/members/verbatim.93103/), [Zodiax](https://www.smogon.com/forums/members/zodiax.202547/), and [Iyarito](https://www.smogon.com/forums/members/iyarito.219578/); converted to Markdown for the PS! website by [Annika](https://www.smogon.com/forums/members/annika.434112/); translated into Japanese by [Dirain1200](https://www.smogon.com/forums/members/dirain1200.558165)) diff --git a/website/pages/proxyhelp-ja.md b/website/pages/proxyhelp-ja.md index b2fb36b190..368be9c1bb 100644 --- a/website/pages/proxyhelp-ja.md +++ b/website/pages/proxyhelp-ja.md @@ -5,9 +5,9 @@ 上記のメッセージが表示され、チャットができない場合は、[プロキシ](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7)または[VPN](https://ja.wikipedia.org/wiki/Virtual_Private_Network)接続を使用しています。以下は、この問題を解決するためのトラブルシューティングの手順です。各手順の後に、ロビーなどのチャットルームで`/logout`と入力し、再度ログインしてください。 - プロキシまたはVPNをオフにします。 - 他のすべてのデバイスでログアウトしていることを確認します。 -- デスクトップクライアントを使用している場合は、代わりに[Webクライアント](https://play.pokemonshowdown.com)を使用してください。 +- Opera、Puffin、BraveなどのブラウザはデフォルトでVPNが有効になっています。[Chrome](https://ja.wikipedia.org/wiki/Google_Chrome)、[Firefox](https://ja.wikipedia.org/wiki/Mozilla_Firefox)、[Safari](https://ja.wikipedia.org/wiki/Safari)など、別のブラウザを使用してください。 +- iCloudプライベートリレーはプロキシ接続とみなされます。お使いのデバイスで有効になっている場合は、無効にしてください。 - TORを使用している場合は、TORを閉じて、一般的なブラウザでShowdownを開いてください。 -- Operaブラウザを使用している場合、デフォルトでVPNが有効になっている可能性があります。[Chrome](https://ja.wikipedia.org/wiki/Google_Chrome)、[Firefox](https://ja.wikipedia.org/wiki/Mozilla_Firefox)、[Safari](https://ja.wikipedia.org/wiki/Safari)などの別のブラウザを使用してみてください。 - 共有ネットワークや商用ネットワークを使用している場合、プロキシやVPNが有効になっている可能性があります。通常のネットワークで接続できるようになるまで待つか、システム管理者に連絡してください。 - 学校や職場で支給されたデバイスを使用している場合、プロキシやVPNソフトウェアが有効になっている可能性があります。別の機器を使用するか、システム管理者に連絡してください。 - チャットで`/ip`と入力してください。あなたのIPが表示されます(123.456.78.910のようなピリオドで区切られた数列です)。[WhatIsMyIPAddress](https://whatismyipaddress.com/)や[IPLocationTools](https://www.iplocationtools.com/)などのWebサイトで、自分のIPを確認します。表示された場所やインターネットサービスプロバイダに見覚えがない場合は、プロキシやVPN接続を利用しています。自宅での接続の場合、知識のある方はネットワーク構成を編集することができます。そうでない場合は、インターネットサービスプロバイダーにお問い合わせください。 From 9b58e8f9dc81ea5aed61d8c2d0ba1559e515b214 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 31 Jan 2022 17:14:54 -0500 Subject: [PATCH 264/770] Add option to match system theme for light/dark mode (#1921) --- js/client-topbar.js | 25 +++++++++++++++++++------ js/client.js | 10 +++++++++- js/storage.js | 11 +++++++++++ src/client-main.ts | 15 +++++++++++++-- src/panel-topbar.tsx | 12 ++++++++---- src/panels.tsx | 13 +++++++++++-- 6 files changed, 71 insertions(+), 15 deletions(-) diff --git a/js/client-topbar.js b/js/client-topbar.js index 713bfa2109..f2eb0d86b0 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -447,13 +447,13 @@ 'change input[name=blockchallenges]': 'setBlockchallenges', 'change input[name=blockpms]': 'setBlockpms', 'change input[name=inchatpm]': 'setInchatpm', - 'change input[name=dark]': 'setDark', 'change input[name=temporarynotifications]': 'setTemporaryNotifications', 'change input[name=refreshprompt]': 'setRefreshprompt', 'change select[name=bg]': 'setBg', 'change select[name=timestamps-lobby]': 'setTimestampsLobby', 'change select[name=timestamps-pms]': 'setTimestampsPMs', 'change select[name=onepanel]': 'setOnePanel', + 'change select[name=theme]': 'setTheme', 'change input[name=logchat]': 'setLogChat', 'change input[name=selfhighlight]': 'setSelfHighlight', 'click img': 'avatars' @@ -477,12 +477,18 @@ buf += '
    '; buf += '

    Graphics

    '; + var theme = Dex.prefs('theme'); + var colorSchemeQuerySupported = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').media !== 'not all'; + buf += '

    '; var onePanel = !!Dex.prefs('onepanel'); if ($(window).width() >= 660) { buf += '

    '; } buf += '

    '; - buf += '

    '; buf += '

    '; if (navigator.userAgent.includes(' Chrome/64.')) { buf += '

    '; @@ -569,10 +575,17 @@ Storage.prefs('nogif', nogif); Dex.loadSpriteData(nogif || Dex.prefs('bwgfx') ? 'bw' : 'xy'); }, - setDark: function (e) { - var dark = !!e.currentTarget.checked; - Storage.prefs('dark', dark); - $('html').toggleClass('dark', dark); + setTheme: function (e) { + var theme = e.currentTarget.value; + Storage.prefs('theme', theme); + if (theme === 'system') { + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + theme = 'dark'; + } else { + theme = 'light'; + } + } + $('html').toggleClass('dark', theme === 'dark'); }, setBwgfx: function (e) { var bwgfx = !!e.currentTarget.checked; diff --git a/js/client.js b/js/client.js index 2af9e09b24..88169f7735 100644 --- a/js/client.js +++ b/js/client.js @@ -467,7 +467,15 @@ function toId() { var muted = Dex.prefs('mute'); BattleSound.setMute(muted); - $('html').toggleClass('dark', !!Dex.prefs('dark')); + var theme = Dex.prefs('theme'); + var colorSchemeQuery = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)'); + var dark = theme === 'dark' || (theme === 'system' && colorSchemeQuery && colorSchemeQuery.matches); + $('html').toggleClass('dark', dark); + if (colorSchemeQuery && colorSchemeQuery.media !== 'not all') { + colorSchemeQuery.addEventListener('change', function (cs) { + if (Dex.prefs('theme') === 'system') $('html').toggleClass('dark', cs.matches); + }); + } var effectVolume = Dex.prefs('effectvolume'); if (effectVolume !== undefined) BattleSound.setEffectVolume(effectVolume); diff --git a/js/storage.js b/js/storage.js index ac9a712d3d..97244f2861 100644 --- a/js/storage.js +++ b/js/storage.js @@ -319,6 +319,17 @@ var updatePrefs = function () { app.addPopupMessage('Your version of Chrome has a bug that makes animated GIFs freeze games sometimes, so certain animations have been disabled. Only some people have the problem, so you can experiment and enable them in the Options menu setting "Disable GIFs for Chrome 64 bug".'); }); } + + var colorSchemeQuerySupported = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').media !== 'not all'; + if (Storage.prefs('theme') === 'system' && !colorSchemeQuerySupported) { + Storage.prefs('theme', null); + } + if (Storage.prefs('dark') !== undefined) { + if (Storage.prefs('dark')) { + Storage.prefs('theme', 'dark'); + } + Storage.prefs('dark', null); + } }; Storage.whenPrefsLoaded(updatePrefs); diff --git a/src/client-main.ts b/src/client-main.ts index 8c73287017..29e7da4a0a 100644 --- a/src/client-main.ts +++ b/src/client-main.ts @@ -29,9 +29,9 @@ const PSPrefsDefaults: {[key: string]: any} = {}; */ class PSPrefs extends PSStreamModel { /** - * Dark mode! + * The theme to use. "system" matches the theme of the system accessing the client. */ - dark = false; + theme: 'light' | 'dark' | 'system' = 'light'; /** * Disables animated GIFs, but keeps other animations enabled. * Workaround for a Chrome 64 bug with GIFs. @@ -128,6 +128,17 @@ class PSPrefs extends PSStreamModel { newPrefs['nogif'] = true; alert('Your version of Chrome has a bug that makes animated GIFs freeze games sometimes, so certain animations have been disabled. Only some people have the problem, so you can experiment and enable them in the Options menu setting "Disable GIFs for Chrome 64 bug".'); } + + const colorSchemeQuerySupported = window.matchMedia?.('(prefers-color-scheme: dark)').media !== 'not all'; + if (newPrefs['theme'] === 'system' && !colorSchemeQuerySupported) { + newPrefs['theme'] = 'light'; + } + if (newPrefs['dark'] !== undefined) { + if (newPrefs['dark']) { + newPrefs['theme'] = 'dark'; + } + delete newPrefs['dark']; + } } } diff --git a/src/panel-topbar.tsx b/src/panel-topbar.tsx index ef407c6289..d26707f000 100644 --- a/src/panel-topbar.tsx +++ b/src/panel-topbar.tsx @@ -450,9 +450,9 @@ PS.roomTypes['volume'] = { }; class OptionsPanel extends PSRoomPanel { - setCheckbox = (e: Event) => { - const checkbox = e.currentTarget as HTMLInputElement; - PS.prefs.set(checkbox.name as 'dark', !!checkbox.checked); + setTheme = (e: Event) => { + const theme = (e.currentTarget as HTMLSelectElement).value as 'light' | 'dark' | 'system'; + PS.prefs.set('theme', theme); this.forceUpdate(); }; render() { @@ -460,7 +460,11 @@ class OptionsPanel extends PSRoomPanel { return

    Graphics

    - +

    ; } diff --git a/src/panels.tsx b/src/panels.tsx index 683935f285..28182ce9de 100644 --- a/src/panels.tsx +++ b/src/panels.tsx @@ -304,9 +304,18 @@ class PSMain extends preact.Component { } }); + const colorSchemeQuery = window.matchMedia?.('(prefers-color-scheme: dark)'); + if (colorSchemeQuery?.media !== 'not all') { + colorSchemeQuery.addEventListener('change', function (cs) { + if (PS.prefs.theme === 'system') document.body.className = cs.matches ? 'dark' : ''; + }); + } + PS.prefs.subscribeAndRun(key => { - if (!key || key === 'dark') { - document.body.className = PS.prefs.dark ? 'dark' : ''; + if (!key || key === 'theme') { + const dark = PS.prefs.theme === 'dark' || + (PS.prefs.theme === 'system' && colorSchemeQuery && colorSchemeQuery.matches); + document.body.className = dark ? 'dark' : ''; } }); } From cea599a226bc6605ded175296b56e10a25272ec0 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Wed, 16 Feb 2022 13:34:27 -0700 Subject: [PATCH 265/770] Teambuilder: Exclude Hisui Pokemon from STABmons (#1942) --- src/battle-dex-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 1229fd5e6f..122ec042f5 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1513,7 +1513,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { if (pokemon.battleOnly && typeof pokemon.battleOnly === 'string') { species = dex.species.get(pokemon.battleOnly); } - const excludedForme = (s: Species) => ['Alola', 'Alola-Totem', 'Galar', 'Galar-Zen'].includes(s.forme); + const excludedForme = (s: Species) => ['Alola', 'Alola-Totem', 'Galar', 'Galar-Zen', 'Hisui'].includes(s.forme); if (baseSpecies.otherFormes && !['Wormadam', 'Urshifu'].includes(baseSpecies.baseSpecies)) { if (!excludedForme(species)) speciesTypes.push(...baseSpecies.types); for (const formeName of baseSpecies.otherFormes) { From 9047b1d0bbebd9dd2d399efb65a32ff9eff261c4 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 16 Feb 2022 16:48:29 -0500 Subject: [PATCH 266/770] Fix PP display for some moves in Gen 1-2 (#1926) --- js/search.js | 15 ++++++++------- src/battle-searchresults.tsx | 6 ++++-- src/battle-tooltips.ts | 3 ++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/js/search.js b/js/search.js index 54eba66afa..8e61425d44 100644 --- a/js/search.js +++ b/js/search.js @@ -560,12 +560,11 @@ buf += ' '; // power, accuracy, pp - var basePower = move.basePower; - var accuracy = move.accuracy; - var pp = move.pp; - buf += '' + (move.category !== 'Status' ? ('Power
    ' + (basePower || '—')) : '') + '
    '; - buf += 'Accuracy
    ' + (accuracy && accuracy !== true ? accuracy + '%' : '—') + '
    '; - buf += 'PP
    ' + (pp === 1 || move.noPPBoosts ? pp : pp * 8 / 5) + '
    '; + var pp = (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5); + if (this.engine && this.engine.dex.gen < 3) pp = Math.min(61, pp); + buf += '' + (move.category !== 'Status' ? ('Power
    ' + (move.basePower || '—')) : '') + '
    '; + buf += 'Accuracy
    ' + (move.accuracy && move.accuracy !== true ? move.accuracy + '%' : '—') + '
    '; + buf += 'PP
    ' + pp + '
    '; // desc buf += '' + BattleLog.escapeHTML(move.shortDesc) + ' '; @@ -598,9 +597,11 @@ buf += ' '; // power, accuracy, pp + var pp = (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5); + if (this.engine && this.engine.dex.gen < 3) pp = Math.min(61, pp); buf += '' + (move.category !== 'Status' ? ('Power
    ' + (move.basePower || '—')) : '') + '
    '; buf += 'Accuracy
    ' + (move.accuracy && move.accuracy !== true ? move.accuracy + '%' : '—') + '
    '; - buf += 'PP
    ' + (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5) + '
    '; + buf += 'PP
    ' + pp + '
    '; // desc buf += '' + BattleLog.escapeHTML(move.shortDesc || move.desc) + ' '; diff --git a/src/battle-searchresults.tsx b/src/battle-searchresults.tsx index 61f99d41f6..f847b8f4de 100644 --- a/src/battle-searchresults.tsx +++ b/src/battle-searchresults.tsx @@ -186,6 +186,8 @@ class PSSearchResults extends preact.Component<{search: DexSearch}> { ; } + let pp = (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5); + if (search.dex.gen < 3) pp = Math.min(61, pp); return
  • {this.renderName(move.name, matchStart, matchEnd, tagStart)} @@ -198,10 +200,10 @@ class PSSearchResults extends preact.Component<{search: DexSearch}> { {move.category !== 'Status' ? [Power,
    , `${move.basePower}` || '\u2014'] : ''} - Accuracy
    ${move.accuracy && move.accuracy !== true ? `${move.accuracy}%` : '\u2014'} + Accuracy
    {move.accuracy && move.accuracy !== true ? `${move.accuracy}%` : '\u2014'}
    - PP
    {move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5} + PP
    {pp}
    {move.shortDesc} diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 99d4212366..9f8b471000 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1264,7 +1264,8 @@ class BattleTooltips { maxpp = 5; } else { move = this.battle.dex.moves.get(moveName); - maxpp = move.noPPBoosts ? move.pp : Math.floor(move.pp * 8 / 5); + maxpp = (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5); + if (this.battle.gen < 3) maxpp = Math.min(61, maxpp); } const bullet = moveName.charAt(0) === '*' || move.isZ ? '' : '•'; if (ppUsed === Infinity) { From 7157c765e048dab9f9059c7a4350dccc693c5139 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 16 Feb 2022 16:48:42 -0500 Subject: [PATCH 267/770] Tooltips: Fix Sticky Web from getting affected by Pressure (#1929) --- src/battle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle.ts b/src/battle.ts index 2bce716186..ac01dbac24 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1433,7 +1433,7 @@ export class Battle { } } let pp = 1; - if (this.abilityActive(['Pressure'])) { + if (this.abilityActive(['Pressure']) && move.id !== 'stickyweb') { const foeTargets = []; const moveTarget = move.pressureTarget; From 0f57bf9ef0ee995b9e32b30a476777a96bacf48e Mon Sep 17 00:00:00 2001 From: 1Mitsuki <64492102+1Mitsuki@users.noreply.github.com> Date: Wed, 16 Feb 2022 18:50:01 -0300 Subject: [PATCH 268/770] Rules: Fix oversight in Portuguese translation (#1939) --- website/pages/rules-pt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/rules-pt.md b/website/pages/rules-pt.md index cb9ca4a776..f1671eb9fd 100755 --- a/website/pages/rules-pt.md +++ b/website/pages/rules-pt.md @@ -36,7 +36,7 @@ Seu nome de usuário pode ser trocado a qualquer momento (mude-o dando log out e 2. **Nomes não podem ofender** um indivíduo ou um grupo (insultar a si mesmo é aceitável, contanto que não seja algo muito sério). -3. **Nomes não podem ter conotação sexual** ou serem excessivamente repugnantes. +3. **Nomes não podem ter conotação sexual** ou ser excessivamente repugnantes. 4. **Nomes não podem fazer propaganda**. From dedfb9fa451e2eaeff93e9b32a6a0ad1cc8b2214 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Wed, 16 Feb 2022 16:45:12 -0600 Subject: [PATCH 269/770] FFA: Move p3 and p4's side conditions (#1941) --- src/battle-animations.ts | 82 ++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 6602d5996a..1022357b14 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -1085,12 +1085,22 @@ export class BattleScene implements BattleSceneStub { if (!this.animating) return; const side = this.battle.sides[siden]; const spriteIndex = +side.isFar; + let x = side.x; + let y = side.y; + if (this.battle.gameType === 'freeforall') { + x += side.isFar ? 20 : -20; + if (side.n > 1) { + x += (side.isFar ? -140 : 140); + y += side.isFar ? 14 : -20; + } + } + switch (id) { case 'auroraveil': const auroraveil = new Sprite(BattleEffects.auroraveil, { display: 'block', - x: side.x, - y: side.y, + x, + y, z: side.behind(-14), xscale: 1, yscale: 0, @@ -1109,8 +1119,8 @@ export class BattleScene implements BattleSceneStub { case 'reflect': const reflect = new Sprite(BattleEffects.reflect, { display: 'block', - x: side.x, - y: side.y, + x, + y, z: side.behind(-17), xscale: 1, yscale: 0, @@ -1129,8 +1139,8 @@ export class BattleScene implements BattleSceneStub { case 'safeguard': const safeguard = new Sprite(BattleEffects.safeguard, { display: 'block', - x: side.x, - y: side.y, + x, + y, z: side.behind(-20), xscale: 1, yscale: 0, @@ -1149,8 +1159,8 @@ export class BattleScene implements BattleSceneStub { case 'lightscreen': const lightscreen = new Sprite(BattleEffects.lightscreen, { display: 'block', - x: side.x, - y: side.y, + x, + y, z: side.behind(-23), xscale: 1, yscale: 0, @@ -1169,8 +1179,8 @@ export class BattleScene implements BattleSceneStub { case 'mist': const mist = new Sprite(BattleEffects.mist, { display: 'block', - x: side.x, - y: side.y, + x, + y, z: side.behind(-27), xscale: 1, yscale: 0, @@ -1189,8 +1199,8 @@ export class BattleScene implements BattleSceneStub { case 'stealthrock': const rock1 = new Sprite(BattleEffects.rock1, { display: 'block', - x: side.leftof(-40), - y: side.y - 10, + x: x + side.leftof(-40), + y: y - 10, z: side.z, opacity: 0.5, scale: 0.2, @@ -1198,8 +1208,8 @@ export class BattleScene implements BattleSceneStub { const rock2 = new Sprite(BattleEffects.rock2, { display: 'block', - x: side.leftof(-20), - y: side.y - 40, + x: x + side.leftof(-20), + y: y - 40, z: side.z, opacity: 0.5, scale: 0.2, @@ -1207,8 +1217,8 @@ export class BattleScene implements BattleSceneStub { const rock3 = new Sprite(BattleEffects.rock1, { display: 'block', - x: side.leftof(30), - y: side.y - 20, + x: x + side.leftof(30), + y: y - 20, z: side.z, opacity: 0.5, scale: 0.2, @@ -1216,8 +1226,8 @@ export class BattleScene implements BattleSceneStub { const rock4 = new Sprite(BattleEffects.rock2, { display: 'block', - x: side.leftof(10), - y: side.y - 30, + x: x + side.leftof(10), + y: y - 30, z: side.z, opacity: 0.5, scale: 0.2, @@ -1232,24 +1242,24 @@ export class BattleScene implements BattleSceneStub { case 'gmaxsteelsurge': const surge1 = new Sprite(BattleEffects.greenmetal1, { display: 'block', - x: side.leftof(-30), - y: side.y - 20, + x: x + side.leftof(-30), + y: y - 20, z: side.z, opacity: 0.5, scale: 0.8, }, this); const surge2 = new Sprite(BattleEffects.greenmetal2, { display: 'block', - x: side.leftof(35), - y: side.y - 15, + x: x + side.leftof(35), + y: y - 15, z: side.z, opacity: 0.5, scale: 0.8, }, this); const surge3 = new Sprite(BattleEffects.greenmetal1, { display: 'block', - x: side.leftof(50), - y: side.y - 10, + x: x + side.leftof(50), + y: y - 10, z: side.z, opacity: 0.5, scale: 0.8, @@ -1270,8 +1280,8 @@ export class BattleScene implements BattleSceneStub { if (spikeArray.length < 1 && levels >= 1) { const spike1 = new Sprite(BattleEffects.caltrop, { display: 'block', - x: side.x - 25, - y: side.y - 40, + x: x - 25, + y: y - 40, z: side.z, scale: 0.3, }, this); @@ -1281,8 +1291,8 @@ export class BattleScene implements BattleSceneStub { if (spikeArray.length < 2 && levels >= 2) { const spike2 = new Sprite(BattleEffects.caltrop, { display: 'block', - x: side.x + 30, - y: side.y - 45, + x: x + 30, + y: y - 45, z: side.z, scale: .3, }, this); @@ -1292,8 +1302,8 @@ export class BattleScene implements BattleSceneStub { if (spikeArray.length < 3 && levels >= 3) { const spike3 = new Sprite(BattleEffects.caltrop, { display: 'block', - x: side.x + 50, - y: side.y - 40, + x: x + 50, + y: y - 40, z: side.z, scale: .3, }, this); @@ -1311,8 +1321,8 @@ export class BattleScene implements BattleSceneStub { if (tspikeArray.length < 1 && tspikeLevels >= 1) { const tspike1 = new Sprite(BattleEffects.poisoncaltrop, { display: 'block', - x: side.x + 5, - y: side.y - 40, + x: x + 5, + y: y - 40, z: side.z, scale: 0.3, }, this); @@ -1322,8 +1332,8 @@ export class BattleScene implements BattleSceneStub { if (tspikeArray.length < 2 && tspikeLevels >= 2) { const tspike2 = new Sprite(BattleEffects.poisoncaltrop, { display: 'block', - x: side.x - 15, - y: side.y - 35, + x: x - 15, + y: y - 35, z: side.z, scale: .3, }, this); @@ -1334,8 +1344,8 @@ export class BattleScene implements BattleSceneStub { case 'stickyweb': const web = new Sprite(BattleEffects.web, { display: 'block', - x: side.x + 15, - y: side.y - 35, + x: x + 15, + y: y - 35, z: side.z, opacity: 0.4, scale: 0.7, From 79a227e0d981823ccc802c6341b4965c30ae021a Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Wed, 16 Feb 2022 16:45:26 -0600 Subject: [PATCH 270/770] FFA: Aim missed moves at the gap in the middle (#1940) --- src/battle-animations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 1022357b14..ea74c64c9f 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -749,7 +749,7 @@ export class BattleScene implements BattleSceneStub { side.missedPokemon = { sprite: new PokemonSprite(null, { - x: side.leftof(-100), + x: side.leftof(this.battle.gameType === 'freeforall' ? -50 : -100), y: side.y, z: side.z, opacity: 0, From 685ea8a9fd1e7bd211ec5d4cd49cab2dd0f79a41 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 16 Feb 2022 17:46:45 -0500 Subject: [PATCH 271/770] Fix visual bug with volume sliders (#1923) --- js/client-topbar.js | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/js/client-topbar.js b/js/client-topbar.js index f2eb0d86b0..4938ae3abe 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -375,9 +375,9 @@ initialize: function (data) { var buf = ''; var muted = !!Dex.prefs('mute'); - buf += '

    ' + (muted ? '(muted)' : '') + '

    '; - buf += '

    ' + (muted ? '(muted)' : '') + '

    '; - buf += '

    ' + (muted ? '(muted)' : '') + '

    '; + buf += '

    ' + (muted ? '(muted)' : '') + '

    '; + buf += '

    ' + (muted ? '(muted)' : '') + '

    '; + buf += '

    ' + (muted ? '(muted)' : '') + '

    '; buf += '

    '; this.$el.html(buf).css('min-width', 160); }, @@ -407,9 +407,9 @@ BattleSound.setMute(muted); if (!muted) { - this.$('.effect-volume').html(''); - this.$('.music-volume').html(''); - this.$('.notif-volume').html(''); + this.$('.effect-volume').html(''); + this.$('.music-volume').html(''); + this.$('.notif-volume').html(''); } else { this.$('.effect-volume').html('(muted)'); this.$('.music-volume').html('(muted)'); @@ -422,12 +422,24 @@ BattleSound.setEffectVolume(volume); Storage.prefs('effectvolume', volume); }, + getEffectVolume: function () { + var volume = Dex.prefs('effectvolume'); + return typeof volume === 'number' ? volume : 50; + }, setMusicVolume: function (volume) { BattleSound.setBgmVolume(volume); Storage.prefs('musicvolume', volume); }, + getMusicVolume: function () { + var volume = Dex.prefs('musicvolume'); + return typeof volume === 'number' ? volume : 50; + }, setNotifVolume: function (volume) { Storage.prefs('notifvolume', volume); + }, + getNotifVolume: function () { + var volume = Dex.prefs('notifvolume'); + return typeof volume === 'number' ? volume : 50; } }); From 466ac4352ff514e81a18e23ded7af5993e23db5c Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 7 Mar 2022 11:31:00 -0500 Subject: [PATCH 272/770] Don't remove type changes for Gmax forme changes (#1945) --- src/battle.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index ac01dbac24..4a29f71066 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2381,9 +2381,11 @@ export class Battle { let species = Dex.species.get(args[2]); let fromeffect = Dex.getEffect(kwArgs.from); let isCustomAnim = species.name.startsWith('Wishiwashi'); - poke.removeVolatile('typeadd' as ID); - poke.removeVolatile('typechange' as ID); - if (this.gen >= 7) poke.removeVolatile('autotomize' as ID); + if (!poke.getSpeciesForme().endsWith('-Gmax') && !species.name.endsWith('-Gmax')) { + poke.removeVolatile('typeadd' as ID); + poke.removeVolatile('typechange' as ID); + if (this.gen >= 6) poke.removeVolatile('autotomize' as ID); + } if (!kwArgs.silent) { this.activateAbility(poke, fromeffect); From 738dd80abd667979517e0e5c4bcccd23c1eec57b Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 20 Mar 2022 14:05:23 -0400 Subject: [PATCH 273/770] Support Gmax sprites without formechange (#1946) --- src/battle-dex.ts | 11 +++++++++-- src/battle.ts | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 21a8628ecb..07591e2fb3 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -492,8 +492,15 @@ const Dex = new class implements ModdedDex { options.shiny = pokemon.shiny; options.gender = pokemon.gender; } - if (pokemon.volatiles.dynamax && options.dynamax !== false) isDynamax = true; - pokemon = pokemon.getSpeciesForme(); + let isGigantamax = false; + if (pokemon.volatiles.dynamax) { + if (pokemon.volatiles.dynamax[1]) { + isGigantamax = true; + } else if (options.dynamax !== false) { + isDynamax = true; + } + } + pokemon = pokemon.getSpeciesForme() + (isGigantamax ? '-Gmax' : ''); } const species = Dex.species.get(pokemon); // Gmax sprites are already extremely large, so we don't need to double. diff --git a/src/battle.ts b/src/battle.ts index 4a29f71066..9b8c8a99dc 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2437,7 +2437,7 @@ export class Battle { this.scene.typeAnim(poke, type); break; case 'dynamax': - poke.addVolatile('dynamax' as ID); + poke.addVolatile('dynamax' as ID, !!args[3]); this.scene.animTransform(poke, true); break; case 'powertrick': From 407b5e6ad0854806e16a2f089688f7a333b7c66d Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 7 Apr 2022 12:03:37 -0700 Subject: [PATCH 274/770] Tooltips: Support Scalemons Mod (#1949) --- src/battle-dex-data.ts | 3 +++ src/battle-tooltips.ts | 17 +++++++++++------ src/battle.ts | 5 ++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index 6daa76ef59..bc2455b2ae 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -1339,6 +1339,7 @@ class Species implements Effect { readonly baseStats: Readonly<{ hp: number, atk: number, def: number, spa: number, spd: number, spe: number, }>; + readonly bst: number; readonly weightkg: number; // flavor data @@ -1390,6 +1391,8 @@ class Species implements Effect { this.types = data.types || ['???']; this.abilities = data.abilities || {0: "No Ability"}; this.baseStats = data.baseStats || {hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0}; + this.bst = this.baseStats.hp + this.baseStats.atk + this.baseStats.def + + this.baseStats.spa + this.baseStats.spd + this.baseStats.spe; this.weightkg = data.weightkg || 0; this.heightm = data.heightm || 0; diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 9f8b471000..c77b2cae14 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1289,11 +1289,17 @@ class BattleTooltips { * Calculates possible Speed stat range of an opponent */ getSpeedRange(pokemon: Pokemon): [number, number] { - if (pokemon.volatiles.transform) { - pokemon = pokemon.volatiles.transform[1]; - } - let level = pokemon.level; - let baseSpe = pokemon.getSpecies().baseStats['spe']; + const tr = Math.trunc || Math.floor; + const species = pokemon.getSpecies(); + let baseSpe = species.baseStats.spe; + if (this.battle.rules['Scalemons Mod']) { + const bstWithoutHp = species.bst - species.baseStats.hp; + const scale = 600 - species.baseStats.hp; + baseSpe = tr(baseSpe * scale / bstWithoutHp); + if (baseSpe < 1) baseSpe = 1; + if (baseSpe > 255) baseSpe = 255; + } + let level = pokemon.volatiles.transform?.[4] || pokemon.level; let tier = this.battle.tier; let gen = this.battle.gen; let isRandomBattle = tier.includes('Random Battle') || @@ -1305,7 +1311,6 @@ class BattleTooltips { let min; let max; - const tr = Math.trunc || Math.floor; if (tier.includes("Let's Go")) { min = tr(tr(tr(2 * baseSpe * level / 100 + 5) * minNature) * tr((70 / 255 / 10 + 1) * 100) / 100); max = tr(tr(tr((2 * baseSpe + maxIv) * level / 100 + 5) * maxNature) * tr((70 / 255 / 10 + 1) * 100) / 100); diff --git a/src/battle.ts b/src/battle.ts index 9b8c8a99dc..81d862d657 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1065,6 +1065,7 @@ export class Battle { tier = ''; gameType: 'singles' | 'doubles' | 'triples' | 'multi' | 'freeforall' = 'singles'; rated: string | boolean = false; + rules: {[ruleName: string]: 1 | 0} = {}; isBlitz = false; endLastTurnPending = false; totalTimeLeft = 0; @@ -2366,7 +2367,8 @@ export class Battle { const pokemon = tpoke; const shiny = tpoke.shiny; const gender = tpoke.gender; - poke.addVolatile('transform' as ID, pokemon, shiny, gender); + const level = tpoke.level; + poke.addVolatile('transform' as ID, pokemon, shiny, gender, level); poke.addVolatile('formechange' as ID, speciesForme); for (const trackedMove of tpoke.moveTrack) { poke.rememberMove(trackedMove[0], 0); @@ -3282,6 +3284,7 @@ export class Battle { this.messageFadeTime = 40; this.isBlitz = true; } + this.rules[ruleName] = 1; this.log(args); break; } From 02ad3bb1b43d86556461fa85ad6bf971bb2f4fcc Mon Sep 17 00:00:00 2001 From: Alexander B <4866817+MathyFurret@users.noreply.github.com> Date: Thu, 7 Apr 2022 14:04:34 -0500 Subject: [PATCH 275/770] Update credits (#1951) --- website/credits.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/credits.php b/website/credits.php index 2d5eb3a867..a5e567b11e 100644 --- a/website/credits.php +++ b/website/credits.php @@ -59,7 +59,7 @@

    Contributors

      -
    • Alexander B. [mathfreak231] – Development

    • +
    • Alexander B. [Mathy] – Development

    • Andrew Goodsell [Zracknel] – Art (battle weather backdrops)

    • Avery Zimmer [Lyren, SolarisFox] – Development

    • Ben Davies [Morfent, Kaiepi] – Development

    • From 98a66faef02aea43072983832076c16216fabc78 Mon Sep 17 00:00:00 2001 From: pacmanboss256 <61611109+pacmanboss256@users.noreply.github.com> Date: Thu, 7 Apr 2022 14:11:23 -0500 Subject: [PATCH 276/770] Categorize more evolution items as useless (#1952) --- build-tools/build-indexes | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index afdabd2a7e..a06583030a 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -756,6 +756,9 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); case 'bottlecap': case 'goldbottlecap': case 'galaricacuff': + case 'chippedpot': + case 'crackedpot': + case 'galaricawreath': badItems.push(id); break; // outclassed items From 9b5938c171bf149c0b0be7632705b12a51ff7674 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Thu, 7 Apr 2022 13:12:29 -0600 Subject: [PATCH 277/770] Add more tiers to the BDSP teambuilder (#1955) --- build-tools/build-indexes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index a06583030a..d028ad8f3e 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -556,7 +556,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); return ["Uber", "OU", "UU", "NFE", "LC"]; } if (isBDSP && !isDoubles) { - return ["CAP", "CAP NFE", "CAP LC", "Uber", "(Uber)", "OU", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "NFE", "LC", "Unreleased"]; + return ["CAP", "CAP NFE", "CAP LC", "Uber", "(Uber)", "OU", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "PUBL", "PU", "(PU)", "NFE", "LC", "Unreleased"]; } if (isVGC) { return ["Mythical", "Restricted Legendary", "Regular", "NFE", "LC"]; From a7fc44ca0542cdec6204fae4e0c617734b3ab19c Mon Sep 17 00:00:00 2001 From: Annika L Date: Sat, 9 Apr 2022 20:45:52 -0700 Subject: [PATCH 278/770] Rules: Add translations for YouTube section --- website/pages/rules-de.md | 4 ++++ website/pages/rules-es.md | 4 ++++ website/pages/rules-fr.md | 4 ++++ website/pages/rules-hi.md | 6 +++++- website/pages/rules-it.md | 4 ++++ website/pages/rules-nl.md | 5 ++++- website/pages/rules-pt.md | 4 ++++ website/pages/rules-tw.md | 4 ++++ website/pages/rules-zh.md | 4 ++++ 9 files changed, 37 insertions(+), 2 deletions(-) diff --git a/website/pages/rules-de.md b/website/pages/rules-de.md index 77cf5bd238..47b59a93f5 100755 --- a/website/pages/rules-de.md +++ b/website/pages/rules-de.md @@ -41,3 +41,7 @@ Du kannst deinen Nutzernamen jederzeit wählen oder ändern. Melde dich einfach 4. **Es ist nicht erlaubt, über Namen Werbung zu machen**. Diese Grundsätze sind weniger streng als an vielen anderen Stellen, deswegen wirst du möglicherweise grenzwertige Namen sehen, die anderswo nicht gestattet würden. Du magst es als unfair empfinden, dass Nutzer diese Namen behalten dürfen. Sollte dies der Fall sein, so entspricht der Name den obigen Regeln und solltest du aufgefordert werden, dir einen neuen Namen auszuwählen, trifft dies nicht auf den deinen zu. + +## YouTube + +Sobald ihr die Befehle `/show` oder `/youtube` für YouTube Videos verwendet, müsst ihr euch im Klaren sein, dass ihr die [Nutzungsbedingungen von YouTube](https://www.youtube.com/static?template=terms&gl=DE) stets beachtet. diff --git a/website/pages/rules-es.md b/website/pages/rules-es.md index 57540335b7..ae59c8e27d 100755 --- a/website/pages/rules-es.md +++ b/website/pages/rules-es.md @@ -41,3 +41,7 @@ Puedes elegir un nombre de usuario y cambiarlo en cualquier momento (lo puedes c 4. **Los nombres no pueden publicitar.** Esta política es mucho menos restrictiva que en otros lugares, por lo que podrán haber ciertos usuarios que estén en "el límite" y no sean aceptados en otros sitios. Si bien puedes considerar injusto que tengan el derecho de conservar su nombre, la diferencia está en que el nombre del otro usuario cumple con nuestras normas, mientras que si tu fuiste forzado a cambiar el nombre, es porque no las cumplías. + +## Youtube + +Cuando utilices los comandos `/show` o `/youtube` para videos de YouTube, deberán seguir los [Términos del Servicio de Youtube](https://www.youtube.com/static?template=terms). diff --git a/website/pages/rules-fr.md b/website/pages/rules-fr.md index ed64cbb76a..539d9e28d2 100755 --- a/website/pages/rules-fr.md +++ b/website/pages/rules-fr.md @@ -41,3 +41,7 @@ Votre pseudo peut être choisi et modifié à tout moment (vous pouvez le change 4. **Les pseudos ne doivent pas être ou faire de la publicité.** Cette politique est moins restrictive que celle de beaucoup d'autres endroits, de sorte que vous pouvez voir quelques pseudos «limites» qui pourraient ne pas être acceptés ailleurs. Vous pourriez également trouver cela injuste que certains utilisateurs soient autorisés à conserver leur pseudo et vous pas. Le fait est que le leur suit les règles plus haut, et si un modérateur vous a demandé de choisir un nouveau pseudo, ce n'est pas le cas du vôtre. + +## YouTube + +Quand vous utilisez les commandes `/show` ou `/youtube` pour des vidéos YouTube, vous devez respecter les [Conditions d’Utilisation de YouTube](https://www.youtube.com/static?gl=IT&template=terms&hl=fr). diff --git a/website/pages/rules-hi.md b/website/pages/rules-hi.md index afd471f5d5..f51e3b68c6 100755 --- a/website/pages/rules-hi.md +++ b/website/pages/rules-hi.md @@ -10,7 +10,7 @@ 3. **यौन संबंधी चीज़ें के बारे में कहीं भी बात न करें** (pms में भी नहीं), अगर आप बालिग हैं तब भी नहीं. -4. **Cheating न करें**. गड़बड़ियों को अपने फायदे के लिए न इस्तेमाल करें. सिस्टम का दुरूपयोग न करें (दोस्तों के खिलाफ़ जान बुझ कर हार के, चालबाज़ी से अपने विरोधी को मुकाबला forfeit करवा के, आदि). Staff की नकल (जैसे उनके जैसे नाम रखना) न +4. **Cheating न करें**. गड़बड़ियों को अपने फायदे के लिए न इस्तेमाल करें. सिस्टम का दुरूपयोग न करें (दोस्तों के खिलाफ़ जान बुझ कर हार के, चालबाज़ी से अपने विरोधी को मुकाबला forfeit करवा के, आदि). Staff की नकल (जैसे उनके जैसे नाम रखना) न 5. **Moderators अपने विवेक से काम कर सकते हैं**. Moderators अपने हिसाब से किसी को दंड दे सकते हैं अगर वो व्यव्हार लिस्ट पे नहीं है तभी भी. अगर आपको किसी Moderator के निर्णय से परेशानी है तो [appeal form](https://play.pokemonshowdown.com/view-help-request--appeal) से appeal कर सकते हैं. @@ -41,3 +41,7 @@ 4. **Usernames से विज्ञापन या प्रचार नहीं कर सकते** ये नीति बाकी जगहों के मुकाबले कम प्रतिबंधक है, तो आपको कुछ "borderline" नाम मिल सकते हैं जो दूसरी जगहों पे नहीं चलते. आपको ये गलत लग सकता है की उन्हें वो नाम रखने दिया गया. अगर उन्हें वो नाम रखने दिया गया और आपको नाम बदलने बोला गया, इसका मतलब ये है की आप ऊपर के नियमों पे खरे नहीं उतरे, लेकिन वो उतरे. + +## YouTube + +YouTube वीडियो के लिए `/show` या `/youtube` कमांड्स के उपयोग पर [YouTube सेवा की शर्तें](https://www.youtube.com/t/terms) मान्य होंगी. diff --git a/website/pages/rules-it.md b/website/pages/rules-it.md index b4e89e67f4..d13e1edc38 100755 --- a/website/pages/rules-it.md +++ b/website/pages/rules-it.md @@ -41,3 +41,7 @@ Il tuo username può essere scelto e cambiato in ogni momento (per farlo fai log 4. **Gli username non possono pubblicizzare**. Questo regolamento è più permissivo di altri che potresti trovare in altri siti, quindi potresti vedere nickname borderline che potrebbero non essere accettati altrove. Di conseguenza, potrebbe sembrarti ingiusto che talvolta tu sia costretto a cambiare il tuo nick mentre altri no. Sta di fatto che se a te è stato chiesto di farlo e a loro no, il loro nickname rispetta le regole qui descritte, mentre il tuo no. + +## YouTube + +Per usare i comandi `/show` o `/youtube` per video di YouTube è necessario attenersi ai [Termini di Servizio di YouTube](https://www.youtube.com/static?gl=IT&template=terms&hl=it). diff --git a/website/pages/rules-nl.md b/website/pages/rules-nl.md index 4951daef06..316bec978f 100755 --- a/website/pages/rules-nl.md +++ b/website/pages/rules-nl.md @@ -19,7 +19,7 @@ ## Chatregels -1. **Volg de regels van de chatroom**, als die er zijn. Chatroomspecifieke regels zullen zichtbaar zijn in een link als je de chat binnenkomt, of je kunt het commando `/rules` gebruiken om de regels van de chatroom te vinden. Chatrooms kunnen regels #2 t/m #5 aanpassen of ongeldig verklaren als ze willen (battles kunnen dit ook, als alle spelers het ermee eens zijn). +1. **Volg de regels van de chatroom**, als die er zijn. Chatroomspecifieke regels zullen zichtbaar zijn in een link als je de chat binnenkomt, of je kunt het commando `/rules` gebruiken om de regels van de chatroom te vinden. Chatrooms kunnen regels #2 t/m #5 aanpassen of ongeldig verklaren als ze willen (battles kunnen dit ook, als alle spelers het ermee eens zijn). 2. **Niet spammen, trollen, of beledigende berichten sturen**. Dit houdt ook in: reclame maken, met een groep mensen samen de chat verstoren en de chat flooden. HOOFDLETTERS en tekstopmaak zijn toegestaan om bepaalde gedeeltes van je bericht te benadrukken, maar gebruik ze met mate. Deze regel geldt ook in privéberichten. @@ -43,3 +43,6 @@ Je kunt op ieder moment een gebruikersnaam kiezen of hem wijzigen (wijzig hem do 4. **Gebruikersnamen mogen niet gebruikt worden om reclame te maken**. Deze regels zijn minder beperkend dan op veel andere plekken, dus het is mogelijk dat je soms "grensgevallen" ziet die op andere plekken niet toegelaten zouden worden. Misschien vind je het oneerlijk dat zij hun naam mogen behouden. Het feit blijft dat zijn of haar naam voldoet aan bovenstaande regels en, als jij gevraagd bent een nieuwe naam te kiezen, de jouwe niet. + +## YouTube +Wanneer `/show` of `/youtube` gebruikt wordt voor YouTube videos, moet je de [Servicevoorwaarden van YouTube](https://www.youtube.com/t/terms) volgen. diff --git a/website/pages/rules-pt.md b/website/pages/rules-pt.md index f1671eb9fd..ffe303c00c 100755 --- a/website/pages/rules-pt.md +++ b/website/pages/rules-pt.md @@ -41,3 +41,7 @@ Seu nome de usuário pode ser trocado a qualquer momento (mude-o dando log out e 4. **Nomes não podem fazer propaganda**. Essas regras são menos restritas aqui do que em outros lugares, logo, é possível que você veja um usuário cujo nome pode estar no limite do aceitável, mas que não seja aceito em outros sites. Você pode até achar injusto que alguém mantenha o nome e você não, mas o fato é que o nome dele segue as regras acima, ao contrário do seu, caso te peçam para mudá-lo. + +## YouTube + +Ao usar os comandos `/show` ou `/youtube` para vídeos do YouTube, é necessário seguir os [Termos de Serviço do YouTube](https://www.youtube.com/static?gl=BR&template=terms&hl=pt). diff --git a/website/pages/rules-tw.md b/website/pages/rules-tw.md index 5054ac9e23..ad5e01850f 100755 --- a/website/pages/rules-tw.md +++ b/website/pages/rules-tw.md @@ -41,3 +41,7 @@ 4. **用戶名不能帶廣告**或者鏈接。 管理員有權強制用戶變更用戶名,請勿以他人的用戶名未被要求變更為理由來為自己的用戶名做辯解。 + +## YouTube + +使用`/show`或`/youtube`指令廣播YouTube視頻的時候請遵守[YouTube服務條款](https://www.youtube.com/t/terms)。 diff --git a/website/pages/rules-zh.md b/website/pages/rules-zh.md index a61bb8bda2..04eee28624 100755 --- a/website/pages/rules-zh.md +++ b/website/pages/rules-zh.md @@ -41,3 +41,7 @@ 4. **用户名不能带广告**或者链接。 管理员有权强制用户变更用户名,请勿以他人的用户名未被要求变更为理由来为自己的用户名做辩解。 + +## YouTube + +使用`/show`或`/youtube`指令广播YouTube视频的时候请遵守[YouTube服务条款](https://www.youtube.com/t/terms)。 From 510e9aa1fc6bb279cc7b893176436b9b21d897fe Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 13 Apr 2022 18:45:09 -0400 Subject: [PATCH 279/770] Fix Ultra Burst text after selecting a move (#1961) --- js/client-battle.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/js/client-battle.js b/js/client-battle.js index 47cd12f4d0..1e2665649e 100644 --- a/js/client-battle.js +++ b/js/client-battle.js @@ -928,13 +928,17 @@ if (parts.length > 2) { var targetPos = parts[2]; if (targetPos === 'mega') { - buf += 'mega evolve, then '; + buf += 'Mega Evolve, then '; targetPos = parts[3]; } if (targetPos === 'zmove') { move = this.request.active[i].canZMove[parseInt(parts[1], 10) - 1].move; targetPos = parts[3]; } + if (targetPos === 'ultra') { + buf += 'Ultra Burst, then '; + targetPos = parts[3]; + } if (targetPos === 'dynamax') { move = this.request.active[i].maxMoves.maxMoves[parseInt(parts[1], 10) - 1].move; buf += 'Dynamax, then '; From 85604da1adb2226dbf1c0fd20ae977339506734e Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Mon, 18 Apr 2022 10:43:05 -0600 Subject: [PATCH 280/770] Unify teambuilder tiers across gens (#1960) --- build-tools/build-indexes | 39 +++++++-------------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index d028ad8f3e..d17394dafa 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -366,8 +366,10 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const ou = Dex.formats.get('gen8nationaldex'); if (Dex.formats.getRuleTable(ou).isBannedSpecies(species)) return 'Uber'; if (Dex.formats.getRuleTable(ou).has('dynamaxclause') && species.name.endsWith('Gmax')) return '(Uber)'; - if (Tags.nduubl.speciesFilter(species)) return 'UUBL'; - if (Dex.formats.getRuleTable(uu).isBannedSpecies(species)) return 'OU'; + if (Dex.formats.getRuleTable(uu).isBannedSpecies(species)) { + if (Tags.nduubl.speciesFilter(species)) return 'UUBL'; + return 'OU'; + } if (Dex.formats.getRuleTable(uu).isRestrictedSpecies(species)) { return 'UU'; } else { @@ -378,7 +380,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); return 'LC'; } } - return '(UU)'; + return 'RU'; } } if (isMetBattle) { @@ -549,51 +551,24 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } const tierOrder = (() => { - if (isNatDex) { - return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "OU", "UUBL", "(OU)", "UU", "(UU)", "NFE", "LC"]; - } - if (isLetsGo) { - return ["Uber", "OU", "UU", "NFE", "LC"]; - } - if (isBDSP && !isDoubles) { - return ["CAP", "CAP NFE", "CAP LC", "Uber", "(Uber)", "OU", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "PUBL", "PU", "(PU)", "NFE", "LC", "Unreleased"]; - } if (isVGC) { return ["Mythical", "Restricted Legendary", "Regular", "NFE", "LC"]; } if (isDoubles && genNum > 4) { return ["DUber", "(DUber)", "DOU", "DBL", "(DOU)", "DUU", "(DUU)", "New", "NFE", "LC"]; } - if (gen === 'gen1' || gen === 'gen2' || gen === 'gen3' || isStadium) { - return ["Uber", "OU", "(OU)", "UUBL", "UU", "NUBL", "NU", "PUBL", "PU", "NFE", "LC"]; - } - if (gen === 'gen4') { - return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "OU", "(OU)", "UUBL", "UU", "NUBL", "NU", "NFE", "LC"]; - } - if (gen === 'gen5') { - return ["CAP", "CAP NFE", "CAP LC", "Uber", "OU", "(OU)", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "PUBL", "PU", "(PU)", "NFE", "LC"]; - } - if (gen === 'gen7') { - return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "OU", "(OU)", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "PUBL", "PU", "(PU)", "NFE", "LC", "Unreleased"]; - } return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "(Uber)", "OU", "(OU)", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "PUBL", "PU", "(PU)", "New", "NFE", "LC", "Unreleased"]; })(); for (const tier of tierOrder) { - if (tier in {OU:1, AG:1, Uber:1, UU:1, "(UU)":1, RU:1, NU:1, "(NU)":1, PU:1, "(PU)":1, NFE:1, LC:1, DOU:1, DUU:1, "(DUU)":1, New:1, Legal:1, Regular:1, "Restricted Legendary":1, "CAP LC":1}) { + if (tier in {OU:1, AG:1, Uber:1, UU:1, RU:1, NU:1, PU:1, "(PU)":1, NFE:1, LC:1, DOU:1, DUU:1, "(DUU)":1, New:1, Legal:1, Regular:1, "Restricted Legendary":1, "CAP LC":1}) { let usedTier = tier; - if (usedTier === "(UU)") usedTier = "RU"; - if (usedTier === "(NU)") usedTier = "PU"; if (usedTier === "(PU)") usedTier = "ZU"; if (usedTier === "(DUU)") usedTier = "DNU"; formatSlices[usedTier] = tiers.length; } if (!tierTable[tier]) continue; - if (tier === "(UU)") { - tiers.push(['header', "Below UU"]); - } else if (tier === "(NU)") { - tiers.push(['header', "Below NU"]); - } else if (tier === "(PU)") { + if (tier === "(PU)") { tiers.push(['header', "Below PU"]); } else if (tier === "(DUU)") { tiers.push(['header', "Below DUU"]); From 93a07b0e5664bf1ec6f1da21a78e5bfa71f66708 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 18 Apr 2022 12:43:34 -0400 Subject: [PATCH 281/770] Teambuilder: List Teleport as a good move in Let's Go (#1959) --- src/battle-dex-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 122ec042f5..665e88ff0f 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1243,7 +1243,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { } if (this.formatType === 'letsgo') { - if (id === 'megadrain') return true; + if (['megadrain', 'teleport'].includes(id)) return true; } if (this.formatType === 'metronome') { From eeaa557b0128b65547890a9c2454f8fd524f50de Mon Sep 17 00:00:00 2001 From: Leonard Craft III Date: Mon, 18 Apr 2022 11:45:00 -0500 Subject: [PATCH 282/770] Tooltips: Fix Eviolite with PLA evolutions (#1964) --- src/battle-tooltips.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index c77b2cae14..d2ade5e774 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1131,7 +1131,12 @@ class BattleTooltips { if (ability === 'marvelscale' && pokemon.status) { stats.def = Math.floor(stats.def * 1.5); } - if (item === 'eviolite' && Dex.species.get(pokemon.speciesForme).evos) { + const isNFE = Dex.species.get(serverPokemon.speciesForme).evos?.some(evo => { + const evoSpecies = Dex.species.get(evo); + return !evoSpecies.isNonstandard || + evoSpecies.isNonstandard === Dex.species.get(serverPokemon.speciesForme)?.isNonstandard; + }); + if (item === 'eviolite' && isNFE) { stats.def = Math.floor(stats.def * 1.5); stats.spd = Math.floor(stats.spd * 1.5); } From 9c9c0f1cae6ebd1ade1e2a23efec07776bb2ec5d Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 25 Apr 2022 17:58:05 -0400 Subject: [PATCH 283/770] Teambuilder: Fix unsketchable moves in past gens (#1965) --- build-tools/build-indexes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index d17394dafa..3eeee788b2 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -938,7 +938,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); // Client relevant data that should be overriden by past gens and mods const overrideSpeciesKeys = ['abilities', 'baseStats', 'cosmeticFormes', 'requiredItems', 'types', 'unreleasedHidden']; - const overrideMoveKeys = ['accuracy', 'basePower', 'category', 'desc', 'flags', 'isNonstandard', 'pp', 'priority', 'shortDesc', 'target', 'type']; + const overrideMoveKeys = ['accuracy', 'basePower', 'category', 'desc', 'flags', 'isNonstandard', 'noSketch', 'pp', 'priority', 'shortDesc', 'target', 'type']; const overrideAbilityKeys = ['desc', 'isNonstandard', 'rating', 'shortDesc']; // From 23c2bd2292306b72a12e22f9e69f73148090205a Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 25 Apr 2022 18:03:53 -0400 Subject: [PATCH 284/770] Tooltips: Properly support Gen 3-4 Knock Off (#1966) --- src/battle.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index 81d862d657..5a1bae448a 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2205,10 +2205,12 @@ export class Battle { let poke = this.getPokemon(args[1])!; let item = Dex.items.get(args[2]); let effect = Dex.getEffect(kwArgs.from); - poke.item = ''; - poke.itemEffect = ''; - poke.prevItem = item.name; - poke.prevItemEffect = ''; + if (this.gen > 4 || effect.id !== 'knockoff') { + poke.item = ''; + poke.itemEffect = ''; + poke.prevItem = item.name; + poke.prevItemEffect = ''; + } poke.removeVolatile('airballoon' as ID); poke.addVolatile('itemremoved' as ID); if (kwArgs.eat) { @@ -2224,7 +2226,11 @@ export class Battle { poke.prevItemEffect = 'flung'; break; case 'knockoff': - poke.prevItemEffect = 'knocked off'; + if (this.gen <= 4) { + poke.itemEffect = 'knocked off'; + } else { + poke.prevItemEffect = 'knocked off'; + } this.scene.runOtherAnim('itemoff' as ID, [poke]); this.scene.resultAnim(poke, 'Item knocked off', 'neutral'); break; From b2f33fb63de0be19303295030a480e881ee1e145 Mon Sep 17 00:00:00 2001 From: Alexander B <4866817+MathyFurret@users.noreply.github.com> Date: Thu, 12 May 2022 20:59:27 -0500 Subject: [PATCH 285/770] Make inline PMs visible on dark mode (#1967) --- style/client.css | 3 +++ style/client2.css | 3 +++ 2 files changed, 6 insertions(+) diff --git a/style/client.css b/style/client.css index ffddb26924..b2d3be8be4 100644 --- a/style/client.css +++ b/style/client.css @@ -3458,6 +3458,9 @@ a.ilink.yours { .dark .highlighted { background: rgba(120,220,255,0.28); } +.dark .message-pm { + color: #00af00; +} .dark .revealed { background: rgba(0,255,200,0.18); } diff --git a/style/client2.css b/style/client2.css index 65b03b1fe2..e664037568 100644 --- a/style/client2.css +++ b/style/client2.css @@ -2173,6 +2173,9 @@ a.ilink.yours { .dark .highlighted { background: rgba(120,220,255,0.28); } +.dark .message-pm { + color: #00af00; +} .dark .revealed { background: rgba(0,255,200,0.18); } From 6cdb2067477a25081fbe4c37d2c3184fb45594fa Mon Sep 17 00:00:00 2001 From: Adam Tran Date: Thu, 12 May 2022 22:11:40 -0400 Subject: [PATCH 286/770] Add source-map dependency (#1970) --- build-tools/compiler.js | 8 ++++---- package.json | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/build-tools/compiler.js b/build-tools/compiler.js index 9a1c664245..5048dc13e2 100644 --- a/build-tools/compiler.js +++ b/build-tools/compiler.js @@ -46,7 +46,7 @@ function slash(path) { return path.replace(/\\/g, '/'); } -function combineResults(fileResults, sourceMapOptions, opts) { +async function combineResults(fileResults, sourceMapOptions, opts) { let map = null; if (fileResults.some(result => result?.map)) { map = new sourceMap.SourceMapGenerator(sourceMapOptions); @@ -61,7 +61,7 @@ function combineResults(fileResults, sourceMapOptions, opts) { code += result.code + "\n"; if (result.map) { - const consumer = new sourceMap.SourceMapConsumer(result.map); + const consumer = await new sourceMap.SourceMapConsumer(result.map); const sources = new Set(); consumer.eachMapping(function (mapping) { @@ -186,7 +186,7 @@ function compileToDir(srcDir, destDir, opts = {}) { return total; } -function compileToFile(srcFile, destFile, opts) { +async function compileToFile(srcFile, destFile, opts) { const incremental = opts.incremental; delete opts.incremental; @@ -209,7 +209,7 @@ function compileToFile(srcFile, destFile, opts) { if (VERBOSE) console.log(src + " ->"); } - const combined = combineResults(results, { + const combined = await combineResults(results, { file: path.basename(destFile), sourceRoot: opts.sourceRoot, }, opts); diff --git a/package.json b/package.json index 629541047d..81b61ad410 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "mocha": "^6.0.2", "preact": "^8.3.1", "tslint": "^5.13.0", - "typescript": "^4.3.2" + "typescript": "^4.3.2", + "source-map": "^0.7.3" }, "private": true } From 239c46eaa34185b03223c9938a5b0a2fe0c1f66e Mon Sep 17 00:00:00 2001 From: Marty-D Date: Sun, 22 May 2022 13:44:31 -0400 Subject: [PATCH 287/770] Teambuilder: Stop zeroing Attack IVs for Gen 5 Nature Power --- js/client-teambuilder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index a10aa12fa3..b2cdf61199 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -3161,7 +3161,7 @@ } else if (move.category === 'Physical' && !move.damage && !move.ohko && !['foulplay', 'endeavor', 'counter', 'bodypress', 'seismictoss', 'bide', 'metalburst', 'superfang'].includes(move.id) && !(this.curTeam.gen < 8 && move.id === 'rapidspin')) { minAtk = false; - } else if (['metronome', 'assist', 'copycat', 'mefirst', 'photongeyser', 'shellsidearm'].includes(move.id)) { + } else if (['metronome', 'assist', 'copycat', 'mefirst', 'photongeyser', 'shellsidearm'].includes(move.id) || (this.curTeam.gen === 5 && move.id === 'naturepower')) { minAtk = false; } if (minSpe === false && moveName === 'Gyro Ball') { From 79e36c7b68f1d9804d56b7b180d9e89aaad1841b Mon Sep 17 00:00:00 2001 From: Marty-D Date: Mon, 30 May 2022 21:20:43 -0400 Subject: [PATCH 288/770] Rename Darach avatar --- src/battle-dex-data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index bc2455b2ae..0f653458d3 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -724,7 +724,7 @@ const BattleAvatarNumbers: {[k: string]: string} = { 92: 'palmer', 93: 'thorton', 94: 'buck', - 95: 'darach', + 95: 'darach-caitlin', 96: 'marley', 97: 'mira', 98: 'cheryl', From 7660ab05478a47ba73ff655c8388a158165259d6 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 30 May 2022 21:21:18 -0400 Subject: [PATCH 289/770] Fix text when switching out after failing a switch move (#1974) --- src/battle.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index 5a1bae448a..33fc308b0d 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -811,8 +811,7 @@ export class Side { return poke; } - switchIn(pokemon: Pokemon, slot?: number) { - if (slot === undefined) slot = pokemon.slot; + switchIn(pokemon: Pokemon, slot = pokemon.slot) { this.active[slot] = pokemon; pokemon.slot = slot; pokemon.clearVolatile(); @@ -867,17 +866,16 @@ export class Side { } this.battle.scene.animSummon(pokemon, slot, true); } - switchOut(pokemon: Pokemon, slot = pokemon.slot) { + switchOut(pokemon: Pokemon, kwArgs: KWArgs, slot = pokemon.slot) { if (pokemon.lastMove !== 'batonpass' && pokemon.lastMove !== 'zbatonpass') { pokemon.clearVolatile(); } else { pokemon.removeVolatile('transform' as ID); pokemon.removeVolatile('formechange' as ID); } - if (pokemon.lastMove === 'uturn' || pokemon.lastMove === 'voltswitch') { - this.battle.log(['switchout', pokemon.ident], {from: pokemon.lastMove}); - } else if (pokemon.lastMove !== 'batonpass' && pokemon.lastMove !== 'zbatonpass') { - this.battle.log(['switchout', pokemon.ident]); + const effect = Dex.getEffect(kwArgs.from); + if (!['batonpass', 'zbatonpass', 'teleport'].includes(effect.id)) { + this.battle.log(['switchout', pokemon.ident], {from: effect.id}); } pokemon.statusData.toxicTurns = 0; if (this.battle.gen === 5) pokemon.statusData.sleepTurns = 0; @@ -3444,7 +3442,7 @@ export class Battle { poke.removeVolatile('itemremoved' as ID); if (args[0] === 'switch') { if (poke.side.active[slot]) { - poke.side.switchOut(poke.side.active[slot]!); + poke.side.switchOut(poke.side.active[slot]!, kwArgs); } poke.side.switchIn(poke); } else if (args[0] === 'replace') { From 857d9407ae39f69b511ab8341091e47804dbf482 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 30 May 2022 21:21:45 -0400 Subject: [PATCH 290/770] Change when accept challenge button gets disabled (#1975) --- js/client-mainmenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index ca9961f32a..4cb3f8d976 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -905,7 +905,6 @@ var $teamButton = $pmWindow.find('button[name=team]'); var privacy = this.adjustPrivacy($pmWindow.find('input[name=private]').is(':checked')); - target.disabled = true; if ($teamButton.length) { var teamIndex = $teamButton.val(); var team = null; @@ -916,6 +915,7 @@ } app.sendTeam(team); } + target.disabled = true; app.send(privacy + '/accept ' + userid); }, rejectChallenge: function (i, target) { From aa32dce7ba722557b18664622eba8ff142b87725 Mon Sep 17 00:00:00 2001 From: May Evans <36418502+PlagueVonKarma@users.noreply.github.com> Date: Mon, 20 Jun 2022 18:01:57 +0100 Subject: [PATCH 291/770] Teambuilder: Update useful/useless Gen 1 moves (#1972) --- src/battle-dex-search.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 665e88ff0f..02a3d3b76d 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1218,14 +1218,14 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { if (dex.gen === 1) { // Usually not useless for Gen 1 if ([ - 'acidarmor', 'amnesia', 'barrier', 'bind', 'blizzard', 'clamp', 'confuseray', 'counter', 'firespin', 'hyperbeam', 'mirrormove', 'pinmissile', 'razorleaf', 'sing', 'slash', 'sludge', 'twineedle', 'wrap', + 'acidarmor', 'amnesia', 'barrier', 'bind', 'blizzard', 'clamp', 'confuseray', 'counter', 'firespin', 'growth', 'headbutt', 'hyperbeam', 'mirrormove', 'pinmissile', 'razorleaf', 'sing', 'slash', 'sludge', 'twineedle', 'wrap', ].includes(id)) { return true; } // Usually useless for Gen 1 if ([ - 'disable', 'firepunch', 'icepunch', 'leechseed', 'quickattack', 'roar', 'thunderpunch', 'toxic', 'triattack', 'whirlwind', + 'disable', 'haze', 'leechseed', 'quickattack', 'roar', 'toxic', 'triattack', 'whirlwind', ].includes(id)) { return false; } @@ -1235,10 +1235,23 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { case 'bubblebeam': return (!moves.includes('surf') && !moves.includes('blizzard')); case 'doubleedge': return !moves.includes('bodyslam'); case 'doublekick': return !moves.includes('submission'); + case 'firepunch': return !moves.includes('fireblast'); case 'megadrain': return !moves.includes('razorleaf') && !moves.includes('surf'); case 'megakick': return !moves.includes('hyperbeam'); case 'reflect': return !moves.includes('barrier') && !moves.includes('acidarmor'); + case 'stomp': return !moves.includes('headbutt'); case 'submission': return !moves.includes('highjumpkick'); + case 'thunderpunch': return !moves.includes('thunderbolt'); + case 'triattack': return !moves.includes('bodyslam'); + } + // Useful and Useless moves for Stadium OU, which changes many game mechanics. + if (this.formatType === 'stadium') { + if (['doubleedge', 'focusenergy', 'haze'].includes(id)) return true; + if (['hyperbeam', 'sing', 'hypnosis'].includes(id)) return false; + switch (id) { + case 'fly': return !moves.includes('drillpeck'); + case 'dig': return !moves.includes('earthquake'); + } } } From 3308d5bcea2c70aee79753ce2f655b2b6cdc9298 Mon Sep 17 00:00:00 2001 From: May Evans <36418502+PlagueVonKarma@users.noreply.github.com> Date: Wed, 22 Jun 2022 16:09:44 +0100 Subject: [PATCH 292/770] Teambuilder: Add more usually useless Gen 1 moves (#1977) --- src/battle-dex-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 02a3d3b76d..a3d7f0ae34 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1225,7 +1225,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { // Usually useless for Gen 1 if ([ - 'disable', 'haze', 'leechseed', 'quickattack', 'roar', 'toxic', 'triattack', 'whirlwind', + 'disable', 'haze', 'leechseed', 'quickattack', 'roar', 'thunder', 'toxic', 'triattack', 'waterfall', 'whirlwind', ].includes(id)) { return false; } From 9ab527b91ae91ef85ab867fdcb00974914bebe87 Mon Sep 17 00:00:00 2001 From: Marty Date: Sun, 26 Jun 2022 11:20:37 -0400 Subject: [PATCH 293/770] Update Pokemon icons sheet --- src/battle-dex-data.ts | 1 + src/battle-dex.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index 0f653458d3..ae794e8adf 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -483,6 +483,7 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { chromera: 1308 + 31, venomicon: 1308 + 32, venomiconepilogue: 1308 + 33, + saharaja: 1308 + 34, syclar: 1344 + 0, embirch: 1344 + 1, diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 07591e2fb3..c9de9c3c5f 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -726,7 +726,7 @@ const Dex = new class implements ModdedDex { let top = Math.floor(num / 12) * 30; let left = (num % 12) * 40; let fainted = ((pokemon as Pokemon | ServerPokemon)?.fainted ? `;opacity:.3;filter:grayscale(100%) brightness(.5)` : ``); - return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v7) no-repeat scroll -${left}px -${top}px${fainted}`; + return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v8) no-repeat scroll -${left}px -${top}px${fainted}`; } getTeambuilderSpriteData(pokemon: any, gen: number = 0): TeambuilderSpriteData { From 0830c457d67368616b340a18357993e5c9314cdc Mon Sep 17 00:00:00 2001 From: Christopher Monsanto Date: Mon, 27 Jun 2022 22:42:03 -0400 Subject: [PATCH 294/770] Disable building sets Removes a dependency on @smogon/sets. Sets will have to be manually copied to data/sets --- build | 3 --- build-tools/build-sets | 25 ------------------------- 2 files changed, 28 deletions(-) delete mode 100755 build-tools/build-sets diff --git a/build b/build index 39bf326611..b4ee9a802f 100755 --- a/build +++ b/build @@ -49,9 +49,6 @@ case 'minidex': case 'sprites': execSync(`node ./build-tools/build-minidex`, options); break; -case 'sets': - execSync(`node ./build-tools/build-sets`, options); - break; case 'replays': execSync(`node ./replays/build`, options); process.exit(); diff --git a/build-tools/build-sets b/build-tools/build-sets deleted file mode 100755 index 1b31202245..0000000000 --- a/build-tools/build-sets +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -const fs = require("fs"); -const child_process = require('child_process'); -const path = require("path"); - -process.stdout.write("Importing sets from @smogon/sets... "); - -const shell = cmd => child_process.execSync(cmd, {stdio: 'inherit', cwd: path.resolve(__dirname, '..')}); -shell(`npm install --no-audit --no-save @smogon/sets`); - -const src = path.resolve(__dirname, '../node_modules/@smogon/sets'); -const dest = path.resolve(__dirname, '../data/sets'); - -try { - fs.mkdirSync(dest); -} catch (err) { - if (err.code !== 'EEXIST') throw err; -} - -for (const file of fs.readdirSync(src)) { - if (!file.endsWith('.json')) continue; - fs.copyFileSync(`${src}/${file}`, `${dest}/${file}`); -} From b5bf36f34ecb5ba1d8182940897b83b71a8499f4 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Thu, 30 Jun 2022 14:48:13 -0400 Subject: [PATCH 295/770] Teambuilder: Fix regression in Gen 4 lower tier display --- build-tools/build-indexes | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 3eeee788b2..12d81f85d4 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -557,6 +557,9 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (isDoubles && genNum > 4) { return ["DUber", "(DUber)", "DOU", "DBL", "(DOU)", "DUU", "(DUU)", "New", "NFE", "LC"]; } + if (gen === 'gen4') { + return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "OU", "(OU)", "UUBL", "UU", "NUBL", "NU", "NFE", "LC"]; + } return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "(Uber)", "OU", "(OU)", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "PUBL", "PU", "(PU)", "New", "NFE", "LC", "Unreleased"]; })(); From ce44085418e5a37a23595af083c11cad3e1f8db0 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 20 Jul 2022 23:47:52 -0400 Subject: [PATCH 296/770] Implement Dynamax Levels (#1805) --- js/client-teambuilder.js | 52 +++++++++++++++++++++++++++----------- js/storage.js | 11 +++++++- src/battle-dex-data.ts | 2 ++ src/battle-tooltips.ts | 2 ++ src/panel-teamdropdown.tsx | 13 +++++++++- 5 files changed, 63 insertions(+), 17 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index b2cdf61199..422637bbdf 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -1222,8 +1222,13 @@ buf += '' + (set.hpType || 'Dark') + ''; } } - if (this.curTeam.gen === 8 && !isBDSP && (species.canGigantamax || species.forme === 'Gmax')) { - buf += '' + (set.gigantamax || species.forme === 'Gmax' ? 'Yes' : 'No') + ''; + if (this.curTeam.gen === 8 && !isBDSP) { + if (!species.cannotDynamax && set.dynamaxLevel !== 10 && set.dynamaxLevel !== undefined) { + buf += '' + (typeof set.dynamaxLevel === 'number' ? set.dynamaxLevel : 10) + ''; + } + if (species.canGigantamax || species.forme === 'Gmax') { + buf += '' + (set.gigantamax || species.forme === 'Gmax' ? 'Yes' : 'No') + ''; + } } } buf += '
  • '; @@ -2624,15 +2629,20 @@ buf += ''; buf += '

    '; - if (!isBDSP && (species.canGigantamax || species.forme === 'Gmax')) { - buf += '
    '; - if (species.forme === 'Gmax') { - buf += 'Yes'; - } else { - buf += ' '; - buf += ''; + if (this.curTeam.gen === 8 && !isBDSP) { + if (!species.cannotDynamax) { + buf += '
    '; + } + if (species.canGigantamax || species.forme === 'Gmax') { + buf += '
    '; + if (species.forme === 'Gmax') { + buf += 'Yes'; + } else { + buf += ' '; + buf += ''; + } + buf += '
    '; } - buf += '
    '; } } @@ -2682,9 +2692,7 @@ // happiness var happiness = parseInt(this.$chart.find('input[name=happiness]').val(), 10); - if (isNaN(happiness)) happiness = 255; - if (happiness > 255) happiness = 255; - if (happiness < 0) happiness = 255; + if (isNaN(happiness) || happiness > 255 || happiness < 0) happiness = 255; set.happiness = happiness; if (set.happiness === 255) delete set.happiness; @@ -2696,6 +2704,12 @@ delete set.shiny; } + // dynamax level + var dynamaxLevel = parseInt(this.$chart.find('input[name=dynamaxlevel]').val(), 10); + if (isNaN(dynamaxLevel) || dynamaxLevel > 10 || dynamaxLevel < 0) dynamaxLevel = 10; + set.dynamaxLevel = dynamaxLevel; + if (set.dynamaxLevel === 10) delete set.dynamaxLevel; + // gigantamax var gmax = (this.$chart.find('input[name=gigantamax]:checked').val() === 'yes'); if (gmax) { @@ -2745,8 +2759,13 @@ } buf += '' + (set.shiny ? 'Yes' : 'No') + ''; if (!isLetsGo && (this.curTeam.gen < 8 || isNatDex)) buf += '' + (set.hpType || 'Dark') + ''; - if (this.curTeam.gen === 8 && !isBDSP && (species.canGigantamax || species.forme === 'Gmax')) { - buf += '' + (set.gigantamax || species.forme === 'Gmax' ? 'Yes' : 'No') + ''; + if (this.curTeam.gen === 8 && !isBDSP) { + if (!species.cannotDynamax) { + buf += '' + (typeof set.dynamaxLevel === 'number' ? set.dynamaxLevel : 10) + ''; + } + if (species.canGigantamax || species.forme === 'Gmax') { + buf += '' + (set.gigantamax || species.forme === 'Gmax' ? 'Yes' : 'No') + ''; + } } } this.$('button[name=details]').html(buf); @@ -2975,6 +2994,7 @@ set.gender = 'F'; if (set.happiness) delete set.happiness; if (set.shiny) delete set.shiny; + if (set.dynamaxLevel) delete set.dynamaxLevel; if (set.gigantamax) delete set.gigantamax; set.item = 'Starf Berry'; set.ability = 'Harvest'; @@ -3004,6 +3024,7 @@ } if (set.happiness) delete set.happiness; if (set.shiny) delete set.shiny; + if (set.dynamaxLevel) delete set.dynamaxLevel; if (set.gigantamax) delete set.gigantamax; set.item = 'Leftovers'; set.ability = 'Battle Armor'; @@ -3222,6 +3243,7 @@ if (species.gender && species.gender !== 'N') set.gender = species.gender; if (set.happiness) delete set.happiness; if (set.shiny) delete set.shiny; + if (set.dynamaxLevel) delete set.dynamaxLevel; if (set.gigantamax) delete set.gigantamax; if (!this.curTeam.format.includes('hackmons') && species.requiredItems.length === 1) { set.item = species.requiredItems[0]; diff --git a/js/storage.js b/js/storage.js index 97244f2861..15c60e2c03 100644 --- a/js/storage.js +++ b/js/storage.js @@ -779,10 +779,11 @@ Storage.packTeam = function (team) { buf += '|'; } - if (set.pokeball || (set.hpType && !hasHP) || set.gigantamax) { + if (set.pokeball || (set.hpType && !hasHP) || set.gigantamax || (set.dynamaxLevel !== undefined && set.dynamaxLevel !== 10)) { buf += ',' + (set.hpType || ''); buf += ',' + toID(set.pokeball); buf += ',' + (set.gigantamax ? 'G' : ''); + buf += ',' + (set.dynamaxLevel !== undefined && set.dynamaxLevel !== 10 ? set.dynamaxLevel : ''); } } @@ -896,6 +897,7 @@ Storage.fastUnpackTeam = function (buf) { set.hpType = misc[1]; set.pokeball = misc[2]; set.gigantamax = !!misc[3]; + set.dynamaxLevel = (misc[4] ? Number(misc[4]) : 10); } if (j < 0) break; i = j + 1; @@ -1012,6 +1014,7 @@ Storage.unpackTeam = function (buf) { set.hpType = misc[1]; set.pokeball = misc[2]; set.gigantamax = !!misc[3]; + set.dynamaxLevel = (misc[4] ? Number(misc[4]) : 10); } if (j < 0) break; i = j + 1; @@ -1190,6 +1193,9 @@ Storage.importTeam = function (buffer, teams) { } else if (line.substr(0, 14) === 'Hidden Power: ') { line = line.substr(14); curSet.hpType = line; + } else if (line.substr(0, 15) === 'Dynamax Level: ') { + line = line.substr(15); + curSet.dynamaxLevel = +line; } else if (line === 'Gigantamax: Yes') { curSet.gigantamax = true; } else if (line.substr(0, 5) === 'EVs: ') { @@ -1311,6 +1317,9 @@ Storage.exportTeam = function (team) { if (curSet.hpType) { text += 'Hidden Power: ' + curSet.hpType + " \n"; } + if (typeof curSet.dynamaxLevel === 'number' && curSet.dynamaxLevel !== 10 && !isNaN(curSet.dynamaxLevel)) { + text += 'Dynamax Level: ' + curSet.dynamaxLevel + " \n"; + } if (curSet.gigantamax) { text += 'Gigantamax: Yes \n'; } diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index ae794e8adf..732dbf6e2f 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -1365,6 +1365,7 @@ class Species implements Effect { readonly tier: string; readonly isTotem: boolean; readonly isMega: boolean; + readonly cannotDynamax: boolean; readonly canGigantamax: boolean; readonly isPrimal: boolean; readonly battleOnly: string | string[] | undefined; @@ -1417,6 +1418,7 @@ class Species implements Effect { this.isTotem = false; this.isMega = !!(this.forme && ['-mega', '-megax', '-megay'].includes(this.formeid)); + this.cannotDynamax = !!data.cannotDynamax; this.canGigantamax = !!data.canGigantamax; this.isPrimal = !!(this.forme && this.formeid === '-primal'); this.battleOnly = data.battleOnly || undefined; diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index d2ade5e774..764f5efbdd 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -2093,6 +2093,8 @@ interface PokemonSet { pokeball?: string; /** Defaults to the type of your Hidden Power in Moves, otherwise Dark */ hpType?: string; + /** Defaults to 10 */ + dynamaxLevel?: number; /** Defaults to no (can only be yes for certain Pokemon) */ gigantamax?: boolean; } diff --git a/src/panel-teamdropdown.tsx b/src/panel-teamdropdown.tsx index 407bbab4a6..733f491c9e 100644 --- a/src/panel-teamdropdown.tsx +++ b/src/panel-teamdropdown.tsx @@ -96,10 +96,14 @@ class PSTeambuilder { buf += '|'; } - if (set.pokeball || (set.hpType && toID(set.hpType) !== hasHP) || set.gigantamax) { + if ( + set.pokeball || (set.hpType && toID(set.hpType) !== hasHP) || set.gigantamax || + (set.dynamaxLevel !== undefined && set.dynamaxLevel !== 10) + ) { buf += ',' + (set.hpType || ''); buf += ',' + toID(set.pokeball); buf += ',' + (set.gigantamax ? 'G' : ''); + buf += ',' + (set.dynamaxLevel !== undefined && set.dynamaxLevel !== 10 ? set.dynamaxLevel : ''); } } @@ -191,6 +195,7 @@ class PSTeambuilder { set.hpType = misc[1]; set.pokeball = misc[2]; set.gigantamax = !!misc[3]; + set.dynamaxLevel = (misc[4] ? Number(misc[4]) : 10); } } @@ -278,6 +283,9 @@ class PSTeambuilder { if (typeof set.happiness === 'number' && set.happiness !== 255 && !isNaN(set.happiness)) { text += `Happiness: ${set.happiness} \n`; } + if (typeof set.dynamaxLevel === 'number' && set.dynamaxLevel !== 255 && !isNaN(set.dynamaxLevel)) { + text += `Dynamax Level: ${set.dynamaxLevel} \n`; + } if (set.gigantamax) { text += `Gigantamax: Yes \n`; } @@ -347,6 +355,9 @@ class PSTeambuilder { } else if (line.startsWith('Hidden Power: ')) { line = line.slice(14); set.hpType = line; + } else if (line.startsWith('Dynamax Level: ')) { + line = line.substr(15); + set.dynamaxLevel = +line; } else if (line === 'Gigantamax: Yes') { set.gigantamax = true; } else if (line.startsWith('EVs: ')) { From 8389a55c9226e41564fdcbc6ffdf6e98f829fc20 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 25 Jul 2022 01:06:44 -0400 Subject: [PATCH 297/770] Teambuilder: Fix Dragon Scale category in Gen 2 (#1981) --- build-tools/build-indexes | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 12d81f85d4..349c9e72ef 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -665,6 +665,10 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (genNum === 2) badItems.push(id); else goodItems.push(id); break; + case 'dragonscale': + if (genNum === 2) goodItems.push(id); + else badItems.push(id); + break; case 'mail': if (genNum >= 6) unreleasedItems.push(id); else goodItems.push(id); @@ -712,7 +716,6 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); case 'electirizer': case 'oldamber': case 'dawnstone': - case 'dragonscale': case 'dubiousdisc': case 'duskstone': case 'firestone': From b94977d28a1ec1f91a3d0e4d32b9be56bca3bb86 Mon Sep 17 00:00:00 2001 From: DavidSyrup <40383543+DavidSyrup@users.noreply.github.com> Date: Mon, 25 Jul 2022 07:20:36 +0200 Subject: [PATCH 298/770] Respect Ignore Nicknames setting in more locations (#1954) --- src/battle-text-parser.ts | 12 +++++++++--- src/battle-tooltips.ts | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 63c93c10e7..8302740039 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -505,10 +505,16 @@ class BattleTextParser { } case 'switchout': { - const [, pokemon] = args; - const side = pokemon.slice(0, 2); + const [, pokemon, details] = args; + const [side, fullname] = this.pokemonFull(pokemon, details); const template = this.template('switchOut', kwArgs.from, this.own(side)); - return template.replace('[TRAINER]', this.trainer(side)).replace('[NICKNAME]', this.pokemonName(pokemon)).replace('[POKEMON]', this.pokemon(pokemon)); + let pokemonName; + if (BattleLog.prefs('ignorenick') === "true") { + pokemonName = fullname; + } else { + pokemonName = this.pokemonName(pokemon) + } + return template.replace('[TRAINER]', this.trainer(side)).replace('[NICKNAME]', pokemonName).replace('[POKEMON]', this.pokemon(pokemon)); } case 'faint': { diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 764f5efbdd..a2943372ec 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -772,8 +772,10 @@ class BattleTooltips { } let name = BattleLog.escapeHTML(pokemon.name); - if (pokemon.speciesForme !== pokemon.name) { + if (pokemon.speciesForme !== pokemon.name && BattleLog.prefs('ignorenicks') === "false") { name += ' (' + BattleLog.escapeHTML(pokemon.speciesForme) + ')'; + } else { + name = BattleLog.escapeHTML(pokemon.speciesForme); } let levelBuf = (pokemon.level !== 100 ? ` L${pokemon.level}` : ``); From 0ed79a61eca8711785adde2889aceac912d868b8 Mon Sep 17 00:00:00 2001 From: Volco <13051425+Volco@users.noreply.github.com> Date: Mon, 25 Jul 2022 01:41:41 -0400 Subject: [PATCH 299/770] Add more backgrounds for battle effects (#1721) --- fx/weather-gravity.png | Bin 0 -> 13262 bytes fx/weather-magicroom.png | Bin 0 -> 13516 bytes fx/weather-wonderroom.png | Bin 0 -> 13585 bytes src/battle-animations.ts | 13 +------------ style/battle.css | 14 +++++++++++++- 5 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 fx/weather-gravity.png create mode 100644 fx/weather-magicroom.png create mode 100644 fx/weather-wonderroom.png diff --git a/fx/weather-gravity.png b/fx/weather-gravity.png new file mode 100644 index 0000000000000000000000000000000000000000..38897958b53346e19eab3fdd3ca99545b867bfa7 GIT binary patch literal 13262 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%0At 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 CiA5Cv literal 0 HcmV?d00001 diff --git a/fx/weather-wonderroom.png b/fx/weather-wonderroom.png new file mode 100644 index 0000000000000000000000000000000000000000..c26ee19fbb3c78f4dad7a051494fdc2d82ce8144 GIT binary patch literal 13585 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 p$hciQx_< Date: Tue, 26 Jul 2022 08:28:39 +0930 Subject: [PATCH 300/770] Fix build error --- src/battle-text-parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 8302740039..3afca4afa3 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -512,7 +512,7 @@ class BattleTextParser { if (BattleLog.prefs('ignorenick') === "true") { pokemonName = fullname; } else { - pokemonName = this.pokemonName(pokemon) + pokemonName = this.pokemonName(pokemon); } return template.replace('[TRAINER]', this.trainer(side)).replace('[NICKNAME]', pokemonName).replace('[POKEMON]', this.pokemon(pokemon)); } From 8406514e4255015094b36ad2a0cb4ca480cf4dae Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Mon, 25 Jul 2022 20:51:23 -0500 Subject: [PATCH 301/770] Add a friend/unfriend option to the UserOptions popup (#1844) --- js/client.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/js/client.js b/js/client.js index 88169f7735..d0f14fb38e 100644 --- a/js/client.js +++ b/js/client.js @@ -2752,7 +2752,11 @@ function toId() { this.close(); }, userOptions: function () { - app.addPopup(UserOptionsPopup, {name: this.data.name, userid: this.data.userid}); + app.addPopup(UserOptionsPopup, { + name: this.data.name, + userid: this.data.userid, + friended: this.data.friended, + }); } }, { dataCache: {} @@ -2762,10 +2766,31 @@ function toId() { initialize: function (data) { this.name = data.name; this.userid = data.userid; + this.data = data; this.update(); }, update: function () { - this.$el.html('

    '); + var ignored = app.ignore[this.userid] ? 'Unignore' : 'Ignore'; + var friended = this.data.friended ? 'Remove friend' : 'Add friend'; + this.$el.html( + '

    ' + + '

    ' + + '

    ' + ); + }, + toggleFriend: function () { + var $button = this.$el.find('[name=toggleFriend]'); + if (this.data.friended) { + app.send('/unfriend ' + this.userid); + $button.text('Friend removed.'); + } else { + app.send('/friend add ' + this.userid); + $button.text('Friend request sent!'); + } + // we intentionally disable since we don't want them to spam it + // you at least have to close and reopen the popup to get it back + $button.addClass('button disabled'); }, report: function () { app.joinRoom('view-help-request-report-user-' + this.userid); From d72857c807d5fa4301c3e2eb15bc571ad07824b4 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Tue, 26 Jul 2022 09:56:32 +0930 Subject: [PATCH 302/770] Preact: Refactor inline style to CSS file --- src/panel-chat.tsx | 2 +- style/client2.css | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/panel-chat.tsx b/src/panel-chat.tsx index d54f8f400e..5258f93798 100644 --- a/src/panel-chat.tsx +++ b/src/panel-chat.tsx @@ -413,7 +413,7 @@ class ChatUserList extends preact.Component<{room: ChatRoom, left?: number, mini [PS.server.getGroup(name.charAt(0)).order, !name.endsWith('@!'), id] )); return
      -
    • {room.userCount} users
    • +
    • {room.userCount} users
    • {userList.map(([userid, name]) => { const groupSymbol = name.charAt(0); const group = PS.server.groups[groupSymbol] || {type: 'user', order: 0}; diff --git a/style/client2.css b/style/client2.css index e664037568..e66e17621f 100644 --- a/style/client2.css +++ b/style/client2.css @@ -1347,6 +1347,10 @@ a.ilink.yours { -webkit-overflow-scrolling: touch; overflow-scrolling: touch; } +.userlist-count { + text-align: center; + padding: 2px 0; +} .userlist-minimized { height: 21px; bottom: auto; From f51402ef6c78818a4beae99da630ea3b1869176d Mon Sep 17 00:00:00 2001 From: Marty Date: Wed, 27 Jul 2022 11:30:34 -0400 Subject: [PATCH 303/770] Revert https://github.com/smogon/pokemon-showdown-client/commit/b94977d28a1ec1f91a3d0e4d32b9be56bca3bb86 --- src/battle-text-parser.ts | 12 +++--------- src/battle-tooltips.ts | 4 +--- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 3afca4afa3..63c93c10e7 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -505,16 +505,10 @@ class BattleTextParser { } case 'switchout': { - const [, pokemon, details] = args; - const [side, fullname] = this.pokemonFull(pokemon, details); + const [, pokemon] = args; + const side = pokemon.slice(0, 2); const template = this.template('switchOut', kwArgs.from, this.own(side)); - let pokemonName; - if (BattleLog.prefs('ignorenick') === "true") { - pokemonName = fullname; - } else { - pokemonName = this.pokemonName(pokemon); - } - return template.replace('[TRAINER]', this.trainer(side)).replace('[NICKNAME]', pokemonName).replace('[POKEMON]', this.pokemon(pokemon)); + return template.replace('[TRAINER]', this.trainer(side)).replace('[NICKNAME]', this.pokemonName(pokemon)).replace('[POKEMON]', this.pokemon(pokemon)); } case 'faint': { diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index a2943372ec..764f5efbdd 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -772,10 +772,8 @@ class BattleTooltips { } let name = BattleLog.escapeHTML(pokemon.name); - if (pokemon.speciesForme !== pokemon.name && BattleLog.prefs('ignorenicks') === "false") { + if (pokemon.speciesForme !== pokemon.name) { name += ' (' + BattleLog.escapeHTML(pokemon.speciesForme) + ')'; - } else { - name = BattleLog.escapeHTML(pokemon.speciesForme); } let levelBuf = (pokemon.level !== 100 ? ` L${pokemon.level}` : ``); From baee58da71f13f429b2b60bf1f375483494cd212 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 22 Aug 2022 12:39:46 -0400 Subject: [PATCH 304/770] Teambuilder: Show Restricteds & Mythicals for Series 13 (#1985) --- src/battle-dex-search.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index a3d7f0ae34..c0e625dbd9 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -921,7 +921,9 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { let slices: {[k: string]: number} = table.formatSlices; if (format === 'ubers' || format === 'uber') tierSet = tierSet.slice(slices.Uber); else if (isVGCOrBS) { - if ( + if (format.endsWith('series13')) { + // Show Mythicals + } else if ( format === 'vgc2010' || format === 'vgc2016' || format.startsWith('vgc2019') || format === 'vgc2022' || format.endsWith('series10') || format.endsWith('series11') ) { From 9cf83da7cf1b2109b647173b7820674b929eace5 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Mon, 22 Aug 2022 10:40:02 -0600 Subject: [PATCH 305/770] Teambuilder: Hardcode out Pikachu-Alola from LGPE (#1986) --- build-tools/build-indexes | 1 + 1 file changed, 1 insertion(+) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 349c9e72ef..10239e9ec4 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -420,6 +420,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); let validNum = (baseSpecies.num <= 151 && species.num >= 1) || [808, 809].includes(baseSpecies.num); if (!validNum) return 'Illegal'; if (species.forme && !['Alola', 'Mega', 'Mega-X', 'Mega-Y', 'Starter'].includes(species.forme)) return 'Illegal'; + if (species.name === 'Pikachu-Alola') return 'Illegal'; return species.tier; } if (isVGC) { From c42bead42762151e3eaf1f0dffe0c657fd3f3bd3 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Mon, 22 Aug 2022 10:40:24 -0600 Subject: [PATCH 306/770] Fix Sinistea's teambuilder learnset (#1988) --- src/battle-dex-search.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index c0e625dbd9..cdd0118f48 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -737,6 +737,7 @@ abstract class BattleTypedSearch { if (lsetSpecies.id === 'gastrodoneast') return 'gastrodon' as ID; if (lsetSpecies.id === 'pumpkaboosuper') return 'pumpkaboo' as ID; + if (lsetSpecies.id === 'sinisteaantique') return 'sinistea' as ID; const next = lsetSpecies.battleOnly || lsetSpecies.changesFrom || lsetSpecies.prevo; if (next) return toID(next); From 03e89bc1221c47d4d10007f4ac34feea104075ce Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Mon, 22 Aug 2022 10:40:53 -0600 Subject: [PATCH 307/770] Teambuilder: Add National Dex RU support (#1989) --- build-tools/build-indexes | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 10239e9ec4..ceb21a6129 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -362,15 +362,17 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); ].map(toID); if (species.isNonstandard && !['Past', 'Gigantamax'].includes(species.isNonstandard)) return 'Illegal'; if (unobtainables.includes(species.id)) return 'Illegal'; - const uu = Dex.formats.get('gen8nationaldexuu'); const ou = Dex.formats.get('gen8nationaldex'); + const uu = Dex.formats.get('gen8nationaldexuu'); + const ru = Dex.formats.get('gen8nationaldexru'); if (Dex.formats.getRuleTable(ou).isBannedSpecies(species)) return 'Uber'; if (Dex.formats.getRuleTable(ou).has('dynamaxclause') && species.name.endsWith('Gmax')) return '(Uber)'; if (Dex.formats.getRuleTable(uu).isBannedSpecies(species)) { if (Tags.nduubl.speciesFilter(species)) return 'UUBL'; return 'OU'; } - if (Dex.formats.getRuleTable(uu).isRestrictedSpecies(species)) { + if (Dex.formats.getRuleTable(ru).isBannedSpecies(species)) { + if (Tags.ndrubl.speciesFilter(species)) return 'RUBL'; return 'UU'; } else { if (species.nfe) { From d4e9642b29e3776a36302ff7c4c4cbdfcd36a6b3 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Wed, 24 Aug 2022 17:40:49 -0600 Subject: [PATCH 308/770] Properly tier National Dex (#1990) --- build-tools/build-indexes | 34 ++++------------------------------ src/battle-dex-search.ts | 3 ++- 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index ceb21a6129..89cb2b114c 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -20,7 +20,6 @@ child_process.execSync('npm run build', {cwd: 'data/pokemon-showdown'}); console.log("DONE"); const Dex = require('../data/pokemon-showdown/.sim-dist/dex').Dex; -const Tags = require('../data/pokemon-showdown/.data-dist/tags').Tags; const toID = Dex.toID; process.stdout.write("Loading gen 6 data... "); Dex.includeData(); @@ -356,35 +355,6 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const baseSpecies = Dex.mod(gen).species.get(species.baseSpecies); if (species.gen > genNum) continue; const tier = (() => { - if (isNatDex) { - const unobtainables = [ - 'Eevee-Starter', 'Floette-Eternal', 'Pichu-Spiky-eared', 'Pikachu-Belle', 'Pikachu-Cosplay', 'Pikachu-Libre', 'Pikachu-PhD', 'Pikachu-Pop-Star', 'Pikachu-Rock-Star', 'Pikachu-Starter', 'Eternatus-Eternamax', - ].map(toID); - if (species.isNonstandard && !['Past', 'Gigantamax'].includes(species.isNonstandard)) return 'Illegal'; - if (unobtainables.includes(species.id)) return 'Illegal'; - const ou = Dex.formats.get('gen8nationaldex'); - const uu = Dex.formats.get('gen8nationaldexuu'); - const ru = Dex.formats.get('gen8nationaldexru'); - if (Dex.formats.getRuleTable(ou).isBannedSpecies(species)) return 'Uber'; - if (Dex.formats.getRuleTable(ou).has('dynamaxclause') && species.name.endsWith('Gmax')) return '(Uber)'; - if (Dex.formats.getRuleTable(uu).isBannedSpecies(species)) { - if (Tags.nduubl.speciesFilter(species)) return 'UUBL'; - return 'OU'; - } - if (Dex.formats.getRuleTable(ru).isBannedSpecies(species)) { - if (Tags.ndrubl.speciesFilter(species)) return 'RUBL'; - return 'UU'; - } else { - if (species.nfe) { - if (species.prevo) { - return 'NFE'; - } else { - return 'LC'; - } - } - return 'RU'; - } - } if (isMetBattle) { let tier = species.tier; if (species.isNonstandard) { @@ -439,6 +409,9 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (isDoubles && genNum > 4) { return species.doublesTier; } + if (isNatDex) { + return species.natDexTier; + } return species.tier; })(); overrideTier[species.id] = tier; @@ -494,6 +467,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (isNatDex) { BattleTeambuilderTable['natdex'] = {}; BattleTeambuilderTable['natdex'].tiers = tiers; + BattleTeambuilderTable['natdex'].overrideTier = overrideTier; BattleTeambuilderTable['natdex'].items = items; BattleTeambuilderTable['natdex'].monotypeBans = monotypeBans; BattleTeambuilderTable['natdex'].formatSlices = formatSlices; diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index cdd0118f48..d8f865e7dc 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -781,7 +781,7 @@ abstract class BattleTypedSearch { return false; } getTier(pokemon: Species) { - if (this.formatType === 'metronome' || this.formatType === 'natdex') { + if (this.formatType === 'metronome') { return pokemon.num >= 0 ? String(pokemon.num) : pokemon.tier; } let table = window.BattleTeambuilderTable; @@ -793,6 +793,7 @@ abstract class BattleTypedSearch { this.formatType === 'nfe' ? `gen${gen}nfe` : this.formatType === 'dlc1' ? 'gen8dlc1' : this.formatType === 'dlc1doubles' ? 'gen8dlc1doubles' : + this.formatType === 'natdex' ? 'natdex' : this.formatType === 'stadium' ? `gen${gen}stadium${gen > 1 ? gen : ''}` : `gen${gen}`; if (table && table[tableKey]) { From fbe9c2d74961fd1f9f77b8d49a2c61106f49a93b Mon Sep 17 00:00:00 2001 From: Marty Date: Wed, 21 Sep 2022 17:04:43 -0400 Subject: [PATCH 309/770] Update credits --- js/storage.js | 2 +- src/client-core.ts | 2 +- website/credits.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/js/storage.js b/js/storage.js index 15c60e2c03..c852ba1b18 100644 --- a/js/storage.js +++ b/js/storage.js @@ -92,7 +92,7 @@ Storage.bg = { break; case 'ocean': hues = ["82.8169014084507,34.63414634146342%", "216.16438356164383,29.55465587044534%", "212.92682926829266,59.42028985507245%", "209.18918918918916,57.51295336787566%", "199.2857142857143,48.275862068965495%", "213.11999999999998,55.06607929515419%"]; - attrib = '
      "Sunrise Ocean" background by Yijing Chen'; + attrib = '"Sunrise Ocean" background by Quanyails'; break; case 'waterfall': hues = ["119.31034482758622,37.66233766233767%", "184.36363636363635,23.012552301255226%", "108.92307692307692,37.14285714285714%", "70.34482758620689,20.567375886524818%", "98.39999999999998,36.76470588235296%", "140,38.18181818181818%"]; diff --git a/src/client-core.ts b/src/client-core.ts index d63fbd5146..bee487d2cf 100644 --- a/src/client-core.ts +++ b/src/client-core.ts @@ -260,7 +260,7 @@ const PSBackground = new class extends PSStreamModel { attrib = { url: 'https://quanyails.deviantart.com/art/Sunrise-Ocean-402667154', title: 'Sunrise Ocean', - artist: 'Yijing Chen', + artist: 'Quanyails', }; break; case 'waterfall': diff --git a/website/credits.php b/website/credits.php index a5e567b11e..15e75e2a38 100644 --- a/website/credits.php +++ b/website/credits.php @@ -98,7 +98,7 @@
    • Kyle Dove – Art (battle backdrops)

    • Vivian Zou [Vtas] – Art (Horizon background)

    • Samuel Teo [Yilx] – Art (Waterfall background)

    • -
    • Yijing Chen [Quanyails] – Art (Ocean background)

    • +
    • [Quanyails] – Art (Ocean background)

    • X/Y and Sun/Moon Sprite Projects led by Ian Clail [Layell]– Sprites

    • Sun/Moon and Sword/Shield Sprite Projects led by [leparagon] – Sprites

    • PKParaíso – Gen 6, 7, and 8 sprite ripping

    • From d6058abdb5e61563c4d256f66f2235570be8f81b Mon Sep 17 00:00:00 2001 From: Leonard Craft III Date: Wed, 21 Sep 2022 16:06:15 -0500 Subject: [PATCH 310/770] Fix more client commands on some Android devices (#1994) --- js/client-chat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-chat.js b/js/client-chat.js index d4c8f90acd..54dabc930d 100644 --- a/js/client-chat.js +++ b/js/client-chat.js @@ -441,7 +441,7 @@ var spaceIndex = text.indexOf(' '); if (spaceIndex > 0) { cmd = text.substr(1, spaceIndex - 1); - target = text.substr(spaceIndex + 1); + target = text.substr(spaceIndex + 1).trim(); } else { cmd = text.substr(1); target = ''; From 1ea5210a360b64ede48813d9572b59b7f3d7365f Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 21 Sep 2022 17:06:56 -0400 Subject: [PATCH 311/770] Stop caching user status (#1993) --- js/client.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/client.js b/js/client.js index d0f14fb38e..b1f76bd38f 100644 --- a/js/client.js +++ b/js/client.js @@ -2619,9 +2619,10 @@ function toId() { update: function (data) { if (data && data.userid === this.data.userid) { data = _.extend(this.data, data); - // Don't cache the roomGroup + // Don't cache the roomGroup or status UserPopup.dataCache[data.userid] = _.clone(data); delete UserPopup.dataCache[data.userid].roomGroup; + delete UserPopup.dataCache[data.userid].status; } else { data = this.data; } From d3357c4f598520a991c85fb0a3b1fbc3831e8710 Mon Sep 17 00:00:00 2001 From: 1Mitsuki <64492102+1Mitsuki@users.noreply.github.com> Date: Wed, 28 Sep 2022 21:48:40 -0300 Subject: [PATCH 312/770] FAQ: Fix typo and header in Portuguese translation (#1997) --- website/pages/faq-pt.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/pages/faq-pt.md b/website/pages/faq-pt.md index 044fb509d1..ce0113d258 100644 --- a/website/pages/faq-pt.md +++ b/website/pages/faq-pt.md @@ -109,9 +109,9 @@ Se você quer saber mais sobre uma tier específica, pode usar o comando `/tier ### Qual é a diferença entre Random Battle e Battle Factory? -Pokémon em Random Battles são gerados aleatoriamente de PU p,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ra cima, enquanto em Battle Factory todos os Pokémon de ambos os times pertencem a mesma tier e possuem movesets competitivos. +Pokémon em Random Battles são gerados aleatoriamente de PU para cima, enquanto em Battle Factory todos os Pokémon de ambos os times pertencem a mesma tier e possuem movesets competitivos. -O que significa GXE? +### O que significa GXE? GXE significa Glick X-Act Estimate. O número mostrado é a estimativa percentual que um jogador tem de vencer contra um adversário qualquer. From 51afc4d350ca23587dc132f423343aab019327af Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 8 Oct 2022 18:03:26 -0400 Subject: [PATCH 313/770] Teambuilder: Fix illegal moves showing in Nintendo formats (#1998) --- build-tools/build-indexes | 20 ++++++++++++-------- src/battle-dex-search.ts | 9 +++------ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 89cb2b114c..8f99de5851 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -807,8 +807,6 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); for (const moveid in learnset) { const gens = learnset[moveid].map(x => Number(x[0])); const minGen = Math.min(...gens); - const vcOnly = (minGen === 7 && learnset[moveid].every(x => x[0] !== '7' || x === '7V') || - minGen === 8 && learnset[moveid].every(x => x[0] !== '8' || x === '8V')); if (minGen <= 4 && (gen3HMs.has(moveid) || gen4HMs.has(moveid))) { let legalGens = ''; @@ -836,8 +834,12 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } if (gens.indexOf(6) >= 0) learnsets[id][moveid] += 'p'; - if (gens.indexOf(7) >= 0 && !vcOnly) learnsets[id][moveid] += 'q'; - if (gens.indexOf(8) >= 0 && !vcOnly) learnsets[id][moveid] += 'g'; + if (gens.indexOf(7) >= 0 && learnset[moveid].some(x => x[0] === '7' && x !== '7V')) { + learnsets[id][moveid] += 'q'; + } + if (gens.indexOf(8) >= 0 && learnset[moveid].some(x => x[0] === '8' && x !== '8V')) { + learnsets[id][moveid] += 'g'; + } } } const G2Learnsets = Dex.mod('gen2').data.Learnsets; @@ -885,8 +887,6 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); for (const moveid in learnset) { const gens = learnset[moveid].map(x => Number(x[0])); const minGen = Math.min(...gens); - const vcOnly = (minGen === 7 && learnset[moveid].every(x => x[0] !== '7' || x === '7V') || - minGen === 8 && learnset[moveid].every(x => x[0] !== '8' || x === '8V')); if (minGen <= 4 && (gen3HMs.has(moveid) || gen4HMs.has(moveid))) { let legalGens = ''; @@ -914,8 +914,12 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } if (gens.indexOf(6) >= 0) BattleTeambuilderTable['gen8dlc1'].learnsets[id][moveid] += 'p'; - if (gens.indexOf(7) >= 0 && !vcOnly) BattleTeambuilderTable['gen8dlc1'].learnsets[id][moveid] += 'q'; - if (gens.indexOf(8) >= 0 && !vcOnly) BattleTeambuilderTable['gen8dlc1'].learnsets[id][moveid] += 'g'; + if (gens.indexOf(7) >= 0 && learnset[moveid].some(x => x[0] === '7' && x !== '7V')) { + BattleTeambuilderTable['gen8dlc1'].learnsets[id][moveid] += 'q'; + } + if (gens.indexOf(8) >= 0 && learnset[moveid].some(x => x[0] === '8' && x !== '8V')) { + BattleTeambuilderTable['gen8dlc1'].learnsets[id][moveid] += 'g'; + } } } diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index d8f865e7dc..4cdce8cc9f 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1430,8 +1430,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { const isHackmons = (format.includes('hackmons') || format.endsWith('bh')); const isSTABmons = (format.includes('stabmons') || format === 'staaabmons'); const isTradebacks = format.includes('tradebacks'); - const galarBornLegality = ((/^battle(stadium|festival)/.test(format) || format.startsWith('vgc')) && - this.dex.gen === 8); + const regionBornLegality = /^battle(spot|stadium|festival)/.test(format) || format.startsWith('vgc'); const abilityid = this.set ? toID(this.set.ability) : '' as ID; const itemid = this.set ? toID(this.set.item) : '' as ID; @@ -1451,10 +1450,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { for (let moveid in learnset) { let learnsetEntry = learnset[moveid]; const move = dex.moves.get(moveid); - /* if (requirePentagon && learnsetEntry.indexOf('p') < 0) { - continue; - } */ - if (galarBornLegality && !learnsetEntry.includes('g')) { + const minGenCode: {[gen: number]: string} = {6: 'p', 7: 'q', 8: 'g'}; + if (regionBornLegality && !learnsetEntry.includes(minGenCode[this.dex.gen])) { continue; } if ( From fc39dcbb90dd76be9ac9d66005e62de36ca54762 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 8 Oct 2022 18:04:28 -0400 Subject: [PATCH 314/770] Teambuilder: Fix incorrect stat label when clicking guessed spread (#1999) --- js/client-teambuilder.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 422637bbdf..c8fe66dbbb 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -1874,7 +1874,8 @@ if (width > 75) width = 75; var color = Math.floor(stats[stat] * 180 / 714); if (color > 360) color = 360; - buf += ' ' + evBuf + ''; + var statName = this.curTeam.gen === 1 && stat === 'spa' ? 'Spc' : BattleStatNames[stat]; + buf += ' ' + evBuf + ''; } this.$('button[name=stats]').html(buf); From 91f40e3b1b9a3dbabbb6a67b38ab787e5c8d7c7a Mon Sep 17 00:00:00 2001 From: Annika <56906084+AnnikaCodes@users.noreply.github.com> Date: Wed, 12 Oct 2022 21:32:26 -0700 Subject: [PATCH 315/770] Website: Remove text about friends list plans --- website/pages/contact.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/website/pages/contact.md b/website/pages/contact.md index b0499ca0df..013e689429 100644 --- a/website/pages/contact.md +++ b/website/pages/contact.md @@ -29,6 +29,3 @@ Mini-FAQ: > > **Found a bug?** > You probably didn't, but if you're sure you did, [Bug Reports](/bugreports). -> -> **2v2 multi battles? Friends list? Translations?** -> These are planned. From 4e5002411cc80ff8044fd586bd0db2f80979b8f6 Mon Sep 17 00:00:00 2001 From: Annika <56906084+AnnikaCodes@users.noreply.github.com> Date: Wed, 12 Oct 2022 21:33:11 -0700 Subject: [PATCH 316/770] Website: Remove friends list from Japanese version --- website/pages/contact-ja.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/website/pages/contact-ja.md b/website/pages/contact-ja.md index efcb46c9dc..a92cda9bfc 100644 --- a/website/pages/contact-ja.md +++ b/website/pages/contact-ja.md @@ -29,6 +29,3 @@ Helpチャットルームでは、ほとんどの問題を解決できます。 > > **バグを見つけました。** > それが既知でないバグである場合は、[Bug Reports](/bugreports)をご覧ください。 -> -> **2v2 multi battlesは? Friends listは? 翻訳プロジェクトは?** -> 実装されました。翻訳プロジェクトは少しずつ進行中です。 From 31f866555ee9d125806f2e8edfa5be1b92d9347e Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 26 Oct 2022 20:29:56 -0400 Subject: [PATCH 317/770] Teambuilder: Fix empty learnsets in old gen vgc formats (#2002) --- src/battle-dex-search.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 4cdce8cc9f..6cc032e059 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1430,7 +1430,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { const isHackmons = (format.includes('hackmons') || format.endsWith('bh')); const isSTABmons = (format.includes('stabmons') || format === 'staaabmons'); const isTradebacks = format.includes('tradebacks'); - const regionBornLegality = /^battle(spot|stadium|festival)/.test(format) || format.startsWith('vgc'); + const regionBornLegality = dex.gen >= 6 && + /^battle(spot|stadium|festival)/.test(format) || format.startsWith('vgc'); const abilityid = this.set ? toID(this.set.ability) : '' as ID; const itemid = this.set ? toID(this.set.item) : '' as ID; @@ -1451,7 +1452,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { let learnsetEntry = learnset[moveid]; const move = dex.moves.get(moveid); const minGenCode: {[gen: number]: string} = {6: 'p', 7: 'q', 8: 'g'}; - if (regionBornLegality && !learnsetEntry.includes(minGenCode[this.dex.gen])) { + if (regionBornLegality && !learnsetEntry.includes(minGenCode[dex.gen])) { continue; } if ( From c3f4ede03addd8c0474d771f66be896f6d9606ba Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 26 Oct 2022 20:30:16 -0400 Subject: [PATCH 318/770] Tooltips: Add Revelationmons Mod support (#2003) --- src/battle-tooltips.ts | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 764f5efbdd..1f91cb1e1d 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1403,26 +1403,36 @@ class BattleTooltips { const noTypeOverride = [ 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'struggle', 'technoblast', 'terrainpulse', 'weatherball', ]; - const allowTypeOverride = !noTypeOverride.includes(move.id); + if (!noTypeOverride.includes(move.id)) { + if (this.battle.rules['Revelationmons Mod']) { + const [types] = pokemon.getTypes(serverPokemon); + for (let i = 0; i < types.length; i++) { + if (serverPokemon.moves[i] && move.id === toID(serverPokemon.moves[i])) { + moveType = types[i]; + } + } + } + + if (category !== 'Status' && !move.isZ && !move.id.startsWith('hiddenpower')) { + if (moveType === 'Normal') { + if (value.abilityModify(0, 'Aerilate')) moveType = 'Flying'; + if (value.abilityModify(0, 'Galvanize')) moveType = 'Electric'; + if (value.abilityModify(0, 'Pixilate')) moveType = 'Fairy'; + if (value.abilityModify(0, 'Refrigerate')) moveType = 'Ice'; + } + if (value.abilityModify(0, 'Normalize')) moveType = 'Normal'; + } - if (allowTypeOverride && category !== 'Status' && !move.isZ && !move.id.startsWith('hiddenpower')) { - if (moveType === 'Normal') { - if (value.abilityModify(0, 'Aerilate')) moveType = 'Flying'; - if (value.abilityModify(0, 'Galvanize')) moveType = 'Electric'; - if (value.abilityModify(0, 'Pixilate')) moveType = 'Fairy'; - if (value.abilityModify(0, 'Refrigerate')) moveType = 'Ice'; + // There aren't any max moves with the sound flag, but if there were, Liquid Voice would make them water type + const isSound = !!( + forMaxMove ? + this.getMaxMoveFromType(moveType, forMaxMove !== true && forMaxMove || undefined) : move + ).flags['sound']; + if (isSound && value.abilityModify(0, 'Liquid Voice')) { + moveType = 'Water'; } - if (value.abilityModify(0, 'Normalize')) moveType = 'Normal'; } - // There aren't any max moves with the sound flag, but if there were, Liquid Voice would make them water type - const isSound = !!( - forMaxMove ? - this.getMaxMoveFromType(moveType, forMaxMove !== true && forMaxMove || undefined) : move - ).flags['sound']; - if (allowTypeOverride && isSound && value.abilityModify(0, 'Liquid Voice')) { - moveType = 'Water'; - } if (this.battle.gen <= 3 && category !== 'Status') { category = Dex.getGen3Category(moveType); } From 3e09140a04c7680cf2d093526756d96a5cad6fa5 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 26 Oct 2022 20:30:46 -0400 Subject: [PATCH 319/770] Reset Sleep/Toxic turns after Healing Wish (#2004) --- src/battle.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/battle.ts b/src/battle.ts index 33fc308b0d..4909fc63a7 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1691,6 +1691,8 @@ export class Battle { this.lastMove = 'healing-wish'; this.scene.runResidualAnim('healingwish' as ID, poke); poke.side.wisher = null; + poke.statusData.sleepTurns = 0; + poke.statusData.toxicTurns = 0; break; case 'wish': this.scene.runResidualAnim('wish' as ID, poke); From 8842fb44ca97f4090d8d78e6b13401c0037e9e10 Mon Sep 17 00:00:00 2001 From: Stephen Arg Date: Sun, 30 Oct 2022 21:36:55 -0400 Subject: [PATCH 320/770] User and active battle counts update on an interval (#2005) --- js/client-rooms.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/js/client-rooms.js b/js/client-rooms.js index ed91f501be..9ad1af54ff 100644 --- a/js/client-rooms.js +++ b/js/client-rooms.js @@ -24,6 +24,12 @@ app.send('/cmd rooms'); app.user.on('change:named', this.updateUser, this); this.update(); + this.chatroomInterval = setInterval(function () { + if (app.curSideRoom && app.curSideRoom.id === 'rooms') { + app.send('/cmd rooms'); + this.update(); + } + }, 20000); }, initSectionSelection: function () { var buf = ['']; @@ -166,6 +172,8 @@ }, closeHide: function () { app.sideRoom = app.curSideRoom = null; + clearInterval(this.chatroomInterval); + this.chatroomInterval = null; this.close(); }, finduser: function () { From 049434bd660777a0b591895a83ee8ad3e9969934 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Thu, 17 Nov 2022 18:46:47 -0700 Subject: [PATCH 321/770] Add Gen 9 (#2011) --- Pokemon-Showdown-Dex | 1 + build-tools/build-indexes | 30 +- js/client-battle.js | 16 +- js/client-mainmenu.js | 2 +- js/client-teambuilder.js | 28 +- js/search.js | 6 +- js/storage.js | 19 +- src/battle-animations-moves.ts | 3 + src/battle-animations.ts | 13 +- src/battle-choices.ts | 16 +- src/battle-dex-data.ts | 971 +++++++++++++++++---------------- src/battle-dex-search.ts | 30 +- src/battle-dex.ts | 14 +- src/battle-text-parser.ts | 36 +- src/battle-tooltips.ts | 7 +- src/battle.ts | 57 +- src/panel-teamdropdown.tsx | 2 +- style/battle.css | 1 + 18 files changed, 721 insertions(+), 531 deletions(-) create mode 160000 Pokemon-Showdown-Dex diff --git a/Pokemon-Showdown-Dex b/Pokemon-Showdown-Dex new file mode 160000 index 0000000000..c1f0abb5b3 --- /dev/null +++ b/Pokemon-Showdown-Dex @@ -0,0 +1 @@ +Subproject commit c1f0abb5b3b37d84b17585e7361e4245418a3db5 diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 8f99de5851..b40ffc33ef 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -315,21 +315,22 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const BattleTeambuilderTable = {}; let buf = '// DO NOT EDIT - automatically built with build-tools/build-indexes\n\n'; - const GENS = [8, 7, 6, 5, 4, 3, 2, 1]; + const GENS = [9, 8, 7, 6, 5, 4, 3, 2, 1]; const DOUBLES = GENS.filter(x => x > 2).map(num => -num); const VGC = GENS.filter(x => x > 3).map(num => -num - 0.5); const NFE = GENS.map(num => num + 0.3); const STADIUM = [2.04, 1.04]; + const NATDEX = [9.1, 8.1]; const OTHER = [8.6, 8.4, 8.2, 8.1, -8.4, -8.6, 7.1]; // process.stdout.write("\n "); - for (const genIdent of [...GENS, ...DOUBLES, ...VGC, ...NFE, ...STADIUM, ...OTHER]) { + for (const genIdent of [...GENS, ...DOUBLES, ...VGC, ...NFE, ...STADIUM, ...OTHER, ...NATDEX]) { const isLetsGo = (genIdent === 7.1); const isBDSP = (genIdent === 8.6 || genIdent === -8.6); const isMetBattle = (genIdent === 8.2); const isNFE = ('' + genIdent).endsWith('.3'); const isDLC1 = (genIdent === 8.4 || genIdent === -8.4); - const isNatDex = (genIdent === 8.1); + const isNatDex = ('' + genIdent).endsWith('.1') && genIdent > 8; const isStadium = ('' + genIdent).endsWith('.04'); const isDoubles = (genIdent < 0); const isVGC = ('' + genIdent).endsWith('.5'); @@ -465,12 +466,12 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const formatSlices = {}; if (isNatDex) { - BattleTeambuilderTable['natdex'] = {}; - BattleTeambuilderTable['natdex'].tiers = tiers; - BattleTeambuilderTable['natdex'].overrideTier = overrideTier; - BattleTeambuilderTable['natdex'].items = items; - BattleTeambuilderTable['natdex'].monotypeBans = monotypeBans; - BattleTeambuilderTable['natdex'].formatSlices = formatSlices; + BattleTeambuilderTable['gen' + genNum + 'natdex'] = {}; + BattleTeambuilderTable['gen' + genNum + 'natdex'].tiers = tiers; + BattleTeambuilderTable['gen' + genNum + 'natdex'].overrideTier = overrideTier; + BattleTeambuilderTable['gen' + genNum + 'natdex'].items = items; + BattleTeambuilderTable['gen' + genNum + 'natdex'].monotypeBans = monotypeBans; + BattleTeambuilderTable['gen' + genNum + 'natdex'].formatSlices = formatSlices; } else if (isMetBattle) { BattleTeambuilderTable['metronome'] = {}; BattleTeambuilderTable['metronome'].tiers = tiers; @@ -504,7 +505,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable[gen + 'doubles'].tiers = tiers; BattleTeambuilderTable[gen + 'doubles'].overrideTier = overrideTier; BattleTeambuilderTable[gen + 'doubles'].formatSlices = formatSlices; - } else if (gen === 'gen8') { + } else if (gen === 'gen9') { BattleTeambuilderTable.tiers = tiers; BattleTeambuilderTable.items = items; BattleTeambuilderTable.overrideTier = overrideTier; @@ -827,10 +828,10 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); let minUpperGen = available ? 5 : Math.min( ...gens.filter(gen => gen > 4) ); - legalGens += '012345678'.slice(minUpperGen); + legalGens += '0123456789'.slice(minUpperGen); learnsets[id][moveid] = legalGens; } else { - learnsets[id][moveid] = '012345678'.slice(minGen); + learnsets[id][moveid] = '0123456789'.slice(minGen); } if (gens.indexOf(6) >= 0) learnsets[id][moveid] += 'p'; @@ -840,6 +841,9 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (gens.indexOf(8) >= 0 && learnset[moveid].some(x => x[0] === '8' && x !== '8V')) { learnsets[id][moveid] += 'g'; } + if (gens.indexOf(9) >= 0 && learnset[moveid].some(x => x[0] === '9' && x !== '9V')) { + learnsets[id][moveid] += 'a'; + } } } const G2Learnsets = Dex.mod('gen2').data.Learnsets; @@ -932,7 +936,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); // Past gen table // - for (const genNum of [7, 6, 5, 4, 3, 2, 1]) { + for (const genNum of [8, 7, 6, 5, 4, 3, 2, 1]) { const gen = 'gen' + genNum; const nextGen = 'gen' + (genNum + 1); const genDex = Dex.mod(gen); diff --git a/js/client-battle.js b/js/client-battle.js index 1e2665649e..25802bf669 100644 --- a/js/client-battle.js +++ b/js/client-battle.js @@ -516,7 +516,11 @@ var switchables = this.request && this.request.side ? this.battle.myPokemon : []; if (type !== 'movetarget') { - while (switchables[this.choice.choices.length] && switchables[this.choice.choices.length].fainted && this.choice.choices.length + 1 < this.battle.nearSide.active.length) { + while ( + switchables[this.choice.choices.length] && + (switchables[this.choice.choices.length].fainted || switchables[this.choice.choices.length].commanding) && + this.choice.choices.length + 1 < this.battle.nearSide.active.length + ) { this.choice.choices.push('pass'); } } @@ -536,6 +540,7 @@ var canDynamax = curActive.canDynamax || switchables[pos].canDynamax; var maxMoves = curActive.maxMoves || switchables[pos].maxMoves; var gigantamax = curActive.gigantamax; + var canTerastallize = curActive.canTerastallize || switchables[pos].canTerastallize; if (canZMove && typeof canZMove[0] === 'string') { canZMove = _.map(canZMove, function (move) { return {move: move, target: Dex.moves.get(move).target}; @@ -698,6 +703,8 @@ moveMenu += '
      '; } else if (canDynamax) { moveMenu += '
      '; + } else if (canTerastallize) { + moveMenu += '
      '; } if (this.finalDecisionMove) { moveMenu += 'You might have some moves disabled, so you won\'t be able to cancel an attack!
      '; @@ -944,6 +951,10 @@ buf += 'Dynamax, then '; targetPos = parts[3]; } + if (targetPos === 'terastallize') { + buf += 'Terastallize, then '; + targetPos = parts[3]; + } if (targetPos) { var targetActive = this.battle.farSide.active; if (targetPos < 0) { @@ -1179,11 +1190,12 @@ var isZMove = !!(this.$('input[name=zmove]')[0] || '').checked; var isUltraBurst = !!(this.$('input[name=ultraburst]')[0] || '').checked; var isDynamax = !!(this.$('input[name=dynamax]')[0] || '').checked; + var isTerastal = !!(this.$('input[name=terastallize]')[0] || '').checked; var target = e.getAttribute('data-target'); var choosableTargets = {normal: 1, any: 1, adjacentAlly: 1, adjacentAllyOrSelf: 1, adjacentFoe: 1}; - this.choice.choices.push('move ' + pos + (isMega ? ' mega' : '') + (isZMove ? ' zmove' : '') + (isUltraBurst ? ' ultra' : '') + (isDynamax ? ' dynamax' : '')); + this.choice.choices.push('move ' + pos + (isMega ? ' mega' : '') + (isZMove ? ' zmove' : '') + (isUltraBurst ? ' ultra' : '') + (isDynamax ? ' dynamax' : '') + (isTerastal ? ' terastallize' : '')); if (nearActive.length > 1 && target in choosableTargets) { this.choice.type = 'movetarget'; this.choice.moveTarget = target; diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index 4cb3f8d976..721edd874d 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -1240,7 +1240,7 @@ var formatName = BattleLog.escapeFormat(format.id); if (formatName.charAt(0) !== '[') formatName = '[Gen 6] ' + formatName; formatName = formatName.replace('[Gen 8 ', '['); - formatName = formatName.replace('[Gen 8] ', ''); + formatName = formatName.replace('[Gen 9] ', ''); formatName = formatName.replace('[Gen 7 ', '['); bufs[curBuf] += '
    • '; } diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index c8fe66dbbb..a67968439d 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -1212,7 +1212,7 @@ buf += '' + (typeof set.happiness === 'number' ? set.happiness : 255) + ''; } buf += '' + (set.shiny ? 'Yes' : 'No') + ''; - if (!isLetsGo) { + if (!isLetsGo && this.curTeam.gen < 9) { if (this.curTeam.gen === 8 && !isNatDex) { if (isBDSP && species.baseSpecies === "Unown") { buf += '' + (set.hpType || 'Dark') + ''; @@ -1230,6 +1230,11 @@ buf += '' + (set.gigantamax || species.forme === 'Gmax' ? 'Yes' : 'No') + ''; } } + if (this.curTeam.gen === 9) { + if (set.teraType) { + buf += '' + (set.teraType || species.types[0]) + ''; + } + } } buf += ''; @@ -2669,6 +2674,16 @@ buf += ''; } + if (this.curTeam.gen === 9) { + buf += '
      '; + } + buf += ''; if (species.cosmeticFormes) { buf += ''; @@ -2743,6 +2758,14 @@ delete set.hpType; } + // Terastal type + var teraType = this.$chart.find('select[name=teratype]').val(); + if (Dex.types.isName(teraType)) { + set.teraType = teraType; + } else { + delete set.teraType; + } + // update details cell var buf = ''; var GenderChart = { @@ -2768,6 +2791,9 @@ buf += '' + (set.gigantamax || species.forme === 'Gmax' ? 'Yes' : 'No') + ''; } } + if (this.curTeam.gen === 9) { + buf += '' + (set.teraType || species.types[0]) + ''; + } } this.$('button[name=details]').html(buf); diff --git a/js/search.js b/js/search.js index 8e61425d44..13ff4ecb12 100644 --- a/js/search.js +++ b/js/search.js @@ -29,7 +29,7 @@ this.externalFilter = false; this.cur = {}; this.$inputEl = null; - this.gen = 8; + this.gen = 9; this.mod = null; this.engine = new DexSearch(); @@ -331,7 +331,7 @@ return buf; } - var gen = this.engine ? this.engine.dex.gen : 8; + var gen = this.engine ? this.engine.dex.gen : 9; // type buf += ''; @@ -776,7 +776,7 @@ return buf; }; - Search.gen = 8; + Search.gen = 9; Search.renderRow = Search.prototype.renderRow; Search.renderPokemonRow = Search.prototype.renderPokemonRow; Search.renderTaggedPokemonRowInner = Search.prototype.renderTaggedPokemonRowInner; diff --git a/js/storage.js b/js/storage.js index c852ba1b18..f075b4f50e 100644 --- a/js/storage.js +++ b/js/storage.js @@ -779,11 +779,12 @@ Storage.packTeam = function (team) { buf += '|'; } - if (set.pokeball || (set.hpType && !hasHP) || set.gigantamax || (set.dynamaxLevel !== undefined && set.dynamaxLevel !== 10)) { + if (set.pokeball || (set.hpType && !hasHP) || set.gigantamax || (set.dynamaxLevel !== undefined && set.dynamaxLevel !== 10) || set.teraType) { buf += ',' + (set.hpType || ''); buf += ',' + toID(set.pokeball); buf += ',' + (set.gigantamax ? 'G' : ''); buf += ',' + (set.dynamaxLevel !== undefined && set.dynamaxLevel !== 10 ? set.dynamaxLevel : ''); + buf += ',' + (set.teraType || ''); } } @@ -888,9 +889,9 @@ Storage.fastUnpackTeam = function (buf) { j = buf.indexOf(']', i); var misc = undefined; if (j < 0) { - if (i < buf.length) misc = buf.substring(i).split(',', 4); + if (i < buf.length) misc = buf.substring(i).split(',', 6); } else { - if (i !== j) misc = buf.substring(i, j).split(',', 4); + if (i !== j) misc = buf.substring(i, j).split(',', 6); } if (misc) { set.happiness = (misc[0] ? Number(misc[0]) : 255); @@ -898,6 +899,7 @@ Storage.fastUnpackTeam = function (buf) { set.pokeball = misc[2]; set.gigantamax = !!misc[3]; set.dynamaxLevel = (misc[4] ? Number(misc[4]) : 10); + set.teraType = misc[5]; } if (j < 0) break; i = j + 1; @@ -1005,9 +1007,9 @@ Storage.unpackTeam = function (buf) { j = buf.indexOf(']', i); var misc = undefined; if (j < 0) { - if (i < buf.length) misc = buf.substring(i).split(',', 4); + if (i < buf.length) misc = buf.substring(i).split(',', 6); } else { - if (i !== j) misc = buf.substring(i, j).split(',', 4); + if (i !== j) misc = buf.substring(i, j).split(',', 6); } if (misc) { set.happiness = (misc[0] ? Number(misc[0]) : 255); @@ -1015,6 +1017,7 @@ Storage.unpackTeam = function (buf) { set.pokeball = misc[2]; set.gigantamax = !!misc[3]; set.dynamaxLevel = (misc[4] ? Number(misc[4]) : 10); + set.teraType = misc[5]; } if (j < 0) break; i = j + 1; @@ -1193,6 +1196,9 @@ Storage.importTeam = function (buffer, teams) { } else if (line.substr(0, 14) === 'Hidden Power: ') { line = line.substr(14); curSet.hpType = line; + } else if (line.substr(0, 15) === 'Terastal Type: ') { + line = line.substr(15); + curSet.teraType = line; } else if (line.substr(0, 15) === 'Dynamax Level: ') { line = line.substr(15); curSet.dynamaxLevel = +line; @@ -1323,6 +1329,9 @@ Storage.exportTeam = function (team) { if (curSet.gigantamax) { text += 'Gigantamax: Yes \n'; } + if (curSet.teraType) { + text += 'Terastal Type: ' + curSet.teraType + " \n"; + } var first = true; if (curSet.evs) { for (var j in BattleStatNames) { diff --git a/src/battle-animations-moves.ts b/src/battle-animations-moves.ts index 81c8a06816..870d203d09 100644 --- a/src/battle-animations-moves.ts +++ b/src/battle-animations-moves.ts @@ -632,6 +632,9 @@ export const BattleMoveAnims: AnimTable = { hail: { anim: BattleOtherAnims.dance.anim, }, + snow: { + anim: BattleOtherAnims.dance.anim, + }, sandstorm: { anim: BattleOtherAnims.dance.anim, }, diff --git a/src/battle-animations.ts b/src/battle-animations.ts index fb3674b445..11b3bb8774 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -924,6 +924,7 @@ export class BattleScene implements BattleSceneStub { primordialsea: 'Heavy Rain', sandstorm: 'Sandstorm', hail: 'Hail', + snow: 'Snow', deltastream: 'Strong Winds', }; weatherhtml = `${weatherNameTable[this.battle.weather] || this.battle.weather}`; @@ -1785,6 +1786,16 @@ export class PokemonSprite extends Sprite { smackdown: ['Smack Down', 'bad'], focusenergy: ['Critical Hit Boost', 'good'], slowstart: ['Slow Start', 'bad'], + protosynthesisatk: ['Protosynthesis: Atk', 'good'], + protosynthesisdef: ['Protosynthesis: Def', 'good'], + protosynthesisspa: ['Protosynthesis: SpA', 'good'], + protosynthesisspd: ['Protosynthesis: SpD', 'good'], + protosynthesisspe: ['Protosynthesis: Spe', 'good'], + quarkdriveatk: ['Quark Drive: Atk', 'good'], + quarkdrivedef: ['Quark Drive: Def', 'good'], + quarkdrivespa: ['Quark Drive: SpA', 'good'], + quarkdrivespd: ['Quark Drive: SpD', 'good'], + quarkdrivespe: ['Quark Drive: Spe', 'good'], noretreat: ['No Retreat', 'bad'], octolock: ['Octolock', 'bad'], tarshot: ['Tar Shot', 'bad'], @@ -2043,7 +2054,7 @@ export class PokemonSprite extends Sprite { reset(pokemon: Pokemon) { this.clearEffects(); - if (pokemon.volatiles.formechange || pokemon.volatiles.dynamax) { + if (pokemon.volatiles.formechange || pokemon.volatiles.dynamax || pokemon.volatiles.terastallize) { if (!this.oldsp) this.oldsp = this.sp; this.sp = Dex.getSpriteData(pokemon, this.isFrontSprite, { gen: this.scene.gen, diff --git a/src/battle-choices.ts b/src/battle-choices.ts index 8d82d1469d..ac19db6a06 100644 --- a/src/battle-choices.ts +++ b/src/battle-choices.ts @@ -42,6 +42,7 @@ interface BattleRequestActivePokemon { canGigantamax?: boolean; canMegaEvo?: boolean; canUltraBurst?: boolean; + canTerastallize?: boolean; trapped?: boolean; maybeTrapped?: boolean; } @@ -84,6 +85,7 @@ interface BattleMoveChoice { ultra: boolean; max: boolean; z: boolean; + tera: boolean; } interface BattleShiftChoice { choiceType: 'shift'; @@ -115,11 +117,13 @@ class BattleChoiceBuilder { ultra: false, z: false, max: false, + tera: false, }; alreadySwitchingIn: number[] = []; alreadyMega = false; alreadyMax = false; alreadyZ = false; + alreadyTera = false; constructor(request: BattleRequest) { this.request = request; @@ -186,17 +190,20 @@ class BattleChoiceBuilder { this.current.ultra = choice.ultra; this.current.z = choice.z; this.current.max = choice.max; + this.current.tera = choice.tera; return null; } } if (choice.mega) this.alreadyMega = true; if (choice.z) this.alreadyZ = true; if (choice.max) this.alreadyMax = true; + if (choice.tera) this.alreadyTera = true; this.current.move = 0; this.current.mega = false; this.current.ultra = false; this.current.z = false; this.current.max = false; + this.current.tera = false; } else if (choice.choiceType === 'switch' || choice.choiceType === 'team') { if (this.alreadySwitchingIn.includes(choice.targetPokemon)) { if (choice.choiceType === 'switch') { @@ -281,6 +288,7 @@ class BattleChoiceBuilder { ultra: false, z: false, max: false, + tera: false, }; while (true) { // If data ends with a number, treat it as a target location. @@ -306,6 +314,12 @@ class BattleChoiceBuilder { } else if (choice.endsWith(' max')) { current.max = true; choice = choice.slice(0, -4); + } else if (choice.endsWith(' terastallize')) { + current.tera = true; + choice = choice.slice(0, -13); + } else if (choice.endsWith(' terastal')) { + current.tera = true; + choice = choice.slice(0, -9); } else { break; } @@ -416,7 +430,7 @@ class BattleChoiceBuilder { switch (choice.choiceType) { case 'move': const target = choice.targetLoc ? ` ${choice.targetLoc > 0 ? '+' : ''}${choice.targetLoc}` : ``; - const boost = `${choice.max ? ' max' : ''}${choice.mega ? ' mega' : ''}${choice.z ? ' zmove' : ''}`; + const boost = `${choice.max ? ' max' : ''}${choice.mega ? ' mega' : ''}${choice.z ? ' zmove' : ''}${choice.tera ? ' terastallize' : ''}`; return `move ${choice.move}${boost}${target}`; case 'switch': case 'team': diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index 732dbf6e2f..2a81f3a381 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -138,221 +138,252 @@ const BattleStatNames = { } as const; const BattleBaseSpeciesChart = [ - "unown", "burmy", "shellos", "gastrodon", "deerling", "sawsbuck", "vivillon", "flabebe", "floette", "florges", "furfrou", "minior", "alcremie", "pokestarufo", "pokestarbrycenman", "pokestarmt", "pokestarmt2", "pokestartransport", "pokestargiant", "pokestarhumanoid", "pokestarmonster", "pokestarf00", "pokestarf002", "pokestarspirit", "pokestarblackdoor", "pokestarwhitedoor", "pokestarblackbelt", + "unown", "burmy", "shellos", "gastrodon", "deerling", "sawsbuck", "vivillon", "flabebe", "floette", "florges", "furfrou", "minior", "alcremie", "tatsugiri", "pokestarufo", "pokestarbrycenman", "pokestarmt", "pokestarmt2", "pokestartransport", "pokestargiant", "pokestarhumanoid", "pokestarmonster", "pokestarf00", "pokestarf002", "pokestarspirit", "pokestarblackdoor", "pokestarwhitedoor", "pokestarblackbelt", ] as ID[]; const BattlePokemonIconIndexes: {[id: string]: number} = { - egg: 900 + 1, - pikachubelle: 900 + 2, - pikachulibre: 900 + 3, - pikachuphd: 900 + 4, - pikachupopstar: 900 + 5, - pikachurockstar: 900 + 6, - pikachucosplay: 900 + 7, - unownexclamation: 900 + 8, - unownquestion: 900 + 9, - unownb: 900 + 10, - unownc: 900 + 11, - unownd: 900 + 12, - unowne: 900 + 13, - unownf: 900 + 14, - unowng: 900 + 15, - unownh: 900 + 16, - unowni: 900 + 17, - unownj: 900 + 18, - unownk: 900 + 19, - unownl: 900 + 20, - unownm: 900 + 21, - unownn: 900 + 22, - unowno: 900 + 23, - unownp: 900 + 24, - unownq: 900 + 25, - unownr: 900 + 26, - unowns: 900 + 27, - unownt: 900 + 28, - unownu: 900 + 29, - unownv: 900 + 30, - unownw: 900 + 31, - unownx: 900 + 32, - unowny: 900 + 33, - unownz: 900 + 34, - castformrainy: 900 + 35, - castformsnowy: 900 + 36, - castformsunny: 900 + 37, - deoxysattack: 900 + 38, - deoxysdefense: 900 + 39, - deoxysspeed: 900 + 40, - burmysandy: 900 + 41, - burmytrash: 900 + 42, - wormadamsandy: 900 + 43, - wormadamtrash: 900 + 44, - cherrimsunshine: 900 + 45, - shelloseast: 900 + 46, - gastrodoneast: 900 + 47, - rotomfan: 900 + 48, - rotomfrost: 900 + 49, - rotomheat: 900 + 50, - rotommow: 900 + 51, - rotomwash: 900 + 52, - giratinaorigin: 900 + 53, - shayminsky: 900 + 54, - unfezantf: 900 + 55, - basculinbluestriped: 900 + 56, - darmanitanzen: 900 + 57, - deerlingautumn: 900 + 58, - deerlingsummer: 900 + 59, - deerlingwinter: 900 + 60, - sawsbuckautumn: 900 + 61, - sawsbucksummer: 900 + 62, - sawsbuckwinter: 900 + 63, - frillishf: 900 + 64, - jellicentf: 900 + 65, - tornadustherian: 900 + 66, - thundurustherian: 900 + 67, - landorustherian: 900 + 68, - kyuremblack: 900 + 69, - kyuremwhite: 900 + 70, - keldeoresolute: 900 + 71, - meloettapirouette: 900 + 72, - vivillonarchipelago: 900 + 73, - vivilloncontinental: 900 + 74, - vivillonelegant: 900 + 75, - vivillonfancy: 900 + 76, - vivillongarden: 900 + 77, - vivillonhighplains: 900 + 78, - vivillonicysnow: 900 + 79, - vivillonjungle: 900 + 80, - vivillonmarine: 900 + 81, - vivillonmodern: 900 + 82, - vivillonmonsoon: 900 + 83, - vivillonocean: 900 + 84, - vivillonpokeball: 900 + 85, - vivillonpolar: 900 + 86, - vivillonriver: 900 + 87, - vivillonsandstorm: 900 + 88, - vivillonsavanna: 900 + 89, - vivillonsun: 900 + 90, - vivillontundra: 900 + 91, - pyroarf: 900 + 92, - flabebeblue: 900 + 93, - flabebeorange: 900 + 94, - flabebewhite: 900 + 95, - flabebeyellow: 900 + 96, - floetteblue: 900 + 97, - floetteeternal: 900 + 98, - floetteorange: 900 + 99, - floettewhite: 900 + 100, - floetteyellow: 900 + 101, - florgesblue: 900 + 102, - florgesorange: 900 + 103, - florgeswhite: 900 + 104, - florgesyellow: 900 + 105, - furfroudandy: 900 + 106, - furfroudebutante: 900 + 107, - furfroudiamond: 900 + 108, - furfrouheart: 900 + 109, - furfroukabuki: 900 + 110, - furfroulareine: 900 + 111, - furfroumatron: 900 + 112, - furfroupharaoh: 900 + 113, - furfroustar: 900 + 114, - meowsticf: 900 + 115, - aegislashblade: 900 + 116, - xerneasneutral: 900 + 117, - hoopaunbound: 900 + 118, - rattataalola: 900 + 119, - raticatealola: 900 + 120, - raichualola: 900 + 121, - sandshrewalola: 900 + 122, - sandslashalola: 900 + 123, - vulpixalola: 900 + 124, - ninetalesalola: 900 + 125, - diglettalola: 900 + 126, - dugtrioalola: 900 + 127, - meowthalola: 900 + 128, - persianalola: 900 + 129, - geodudealola: 900 + 130, - graveleralola: 900 + 131, - golemalola: 900 + 132, - grimeralola: 900 + 133, - mukalola: 900 + 134, - exeggutoralola: 900 + 135, - marowakalola: 900 + 136, - greninjaash: 900 + 137, - zygarde10: 900 + 138, - zygardecomplete: 900 + 139, - oricoriopompom: 900 + 140, - oricoriopau: 900 + 141, - oricoriosensu: 900 + 142, - lycanrocmidnight: 900 + 143, - wishiwashischool: 900 + 144, - miniormeteor: 900 + 145, - miniororange: 900 + 146, - minioryellow: 900 + 147, - miniorgreen: 900 + 148, - miniorblue: 900 + 149, - miniorindigo: 900 + 150, - miniorviolet: 900 + 151, - magearnaoriginal: 900 + 152, - pikachuoriginal: 900 + 153, - pikachuhoenn: 900 + 154, - pikachusinnoh: 900 + 155, - pikachuunova: 900 + 156, - pikachukalos: 900 + 157, - pikachualola: 900 + 158, - pikachupartner: 900 + 159, - lycanrocdusk: 900 + 160, - necrozmaduskmane: 900 + 161, - necrozmadawnwings: 900 + 162, - necrozmaultra: 900 + 163, - pikachustarter: 900 + 164, - eeveestarter: 900 + 165, - meowthgalar: 900 + 166, - ponytagalar: 900 + 167, - rapidashgalar: 900 + 168, - farfetchdgalar: 900 + 169, - weezinggalar: 900 + 170, - mrmimegalar: 900 + 171, - corsolagalar: 900 + 172, - zigzagoongalar: 900 + 173, - linoonegalar: 900 + 174, - darumakagalar: 900 + 175, - darmanitangalar: 900 + 176, - darmanitangalarzen: 900 + 177, - yamaskgalar: 900 + 178, - stunfiskgalar: 900 + 179, - cramorantgulping: 900 + 180, - cramorantgorging: 900 + 181, - toxtricitylowkey: 900 + 182, + egg: 1020 + 1, + pikachubelle: 1020 + 2, + pikachulibre: 1020 + 3, + pikachuphd: 1020 + 4, + pikachupopstar: 1020 + 5, + pikachurockstar: 1020 + 6, + pikachucosplay: 1020 + 7, + unownexclamation: 1020 + 8, + unownquestion: 1020 + 9, + unownb: 1020 + 10, + unownc: 1020 + 11, + unownd: 1020 + 12, + unowne: 1020 + 13, + unownf: 1020 + 14, + unowng: 1020 + 15, + unownh: 1020 + 16, + unowni: 1020 + 17, + unownj: 1020 + 18, + unownk: 1020 + 19, + unownl: 1020 + 20, + unownm: 1020 + 21, + unownn: 1020 + 22, + unowno: 1020 + 23, + unownp: 1020 + 24, + unownq: 1020 + 25, + unownr: 1020 + 26, + unowns: 1020 + 27, + unownt: 1020 + 28, + unownu: 1020 + 29, + unownv: 1020 + 30, + unownw: 1020 + 31, + unownx: 1020 + 32, + unowny: 1020 + 33, + unownz: 1020 + 34, + castformrainy: 1020 + 35, + castformsnowy: 1020 + 36, + castformsunny: 1020 + 37, + deoxysattack: 1020 + 38, + deoxysdefense: 1020 + 39, + deoxysspeed: 1020 + 40, + burmysandy: 1020 + 41, + burmytrash: 1020 + 42, + wormadamsandy: 1020 + 43, + wormadamtrash: 1020 + 44, + cherrimsunshine: 1020 + 45, + shelloseast: 1020 + 46, + gastrodoneast: 1020 + 47, + rotomfan: 1020 + 48, + rotomfrost: 1020 + 49, + rotomheat: 1020 + 50, + rotommow: 1020 + 51, + rotomwash: 1020 + 52, + giratinaorigin: 1020 + 53, + shayminsky: 1020 + 54, + unfezantf: 1020 + 55, + basculinbluestriped: 1020 + 56, + darmanitanzen: 1020 + 57, + deerlingautumn: 1020 + 58, + deerlingsummer: 1020 + 59, + deerlingwinter: 1020 + 60, + sawsbuckautumn: 1020 + 61, + sawsbucksummer: 1020 + 62, + sawsbuckwinter: 1020 + 63, + frillishf: 1020 + 64, + jellicentf: 1020 + 65, + tornadustherian: 1020 + 66, + thundurustherian: 1020 + 67, + landorustherian: 1020 + 68, + kyuremblack: 1020 + 69, + kyuremwhite: 1020 + 70, + keldeoresolute: 1020 + 71, + meloettapirouette: 1020 + 72, + vivillonarchipelago: 1020 + 73, + vivilloncontinental: 1020 + 74, + vivillonelegant: 1020 + 75, + vivillonfancy: 1020 + 76, + vivillongarden: 1020 + 77, + vivillonhighplains: 1020 + 78, + vivillonicysnow: 1020 + 79, + vivillonjungle: 1020 + 80, + vivillonmarine: 1020 + 81, + vivillonmodern: 1020 + 82, + vivillonmonsoon: 1020 + 83, + vivillonocean: 1020 + 84, + vivillonpokeball: 1020 + 85, + vivillonpolar: 1020 + 86, + vivillonriver: 1020 + 87, + vivillonsandstorm: 1020 + 88, + vivillonsavanna: 1020 + 89, + vivillonsun: 1020 + 90, + vivillontundra: 1020 + 91, + pyroarf: 1020 + 92, + flabebeblue: 1020 + 93, + flabebeorange: 1020 + 94, + flabebewhite: 1020 + 95, + flabebeyellow: 1020 + 96, + floetteblue: 1020 + 97, + floetteeternal: 1020 + 98, + floetteorange: 1020 + 99, + floettewhite: 1020 + 100, + floetteyellow: 1020 + 101, + florgesblue: 1020 + 102, + florgesorange: 1020 + 103, + florgeswhite: 1020 + 104, + florgesyellow: 1020 + 105, + furfroudandy: 1020 + 106, + furfroudebutante: 1020 + 107, + furfroudiamond: 1020 + 108, + furfrouheart: 1020 + 109, + furfroukabuki: 1020 + 110, + furfroulareine: 1020 + 111, + furfroumatron: 1020 + 112, + furfroupharaoh: 1020 + 113, + furfroustar: 1020 + 114, + meowsticf: 1020 + 115, + aegislashblade: 1020 + 116, + xerneasneutral: 1020 + 117, + hoopaunbound: 1020 + 118, + rattataalola: 1020 + 119, + raticatealola: 1020 + 120, + raichualola: 1020 + 121, + sandshrewalola: 1020 + 122, + sandslashalola: 1020 + 123, + vulpixalola: 1020 + 124, + ninetalesalola: 1020 + 125, + diglettalola: 1020 + 126, + dugtrioalola: 1020 + 127, + meowthalola: 1020 + 128, + persianalola: 1020 + 129, + geodudealola: 1020 + 130, + graveleralola: 1020 + 131, + golemalola: 1020 + 132, + grimeralola: 1020 + 133, + mukalola: 1020 + 134, + exeggutoralola: 1020 + 135, + marowakalola: 1020 + 136, + greninjaash: 1020 + 137, + zygarde10: 1020 + 138, + zygardecomplete: 1020 + 139, + oricoriopompom: 1020 + 140, + oricoriopau: 1020 + 141, + oricoriosensu: 1020 + 142, + lycanrocmidnight: 1020 + 143, + wishiwashischool: 1020 + 144, + miniormeteor: 1020 + 145, + miniororange: 1020 + 146, + minioryellow: 1020 + 147, + miniorgreen: 1020 + 148, + miniorblue: 1020 + 149, + miniorindigo: 1020 + 150, + miniorviolet: 1020 + 151, + magearnaoriginal: 1020 + 152, + pikachuoriginal: 1020 + 153, + pikachuhoenn: 1020 + 154, + pikachusinnoh: 1020 + 155, + pikachuunova: 1020 + 156, + pikachukalos: 1020 + 157, + pikachualola: 1020 + 158, + pikachupartner: 1020 + 159, + lycanrocdusk: 1020 + 160, + necrozmaduskmane: 1020 + 161, + necrozmadawnwings: 1020 + 162, + necrozmaultra: 1020 + 163, + pikachustarter: 1020 + 164, + eeveestarter: 1020 + 165, + meowthgalar: 1020 + 166, + ponytagalar: 1020 + 167, + rapidashgalar: 1020 + 168, + farfetchdgalar: 1020 + 169, + weezinggalar: 1020 + 170, + mrmimegalar: 1020 + 171, + corsolagalar: 1020 + 172, + zigzagoongalar: 1020 + 173, + linoonegalar: 1020 + 174, + darumakagalar: 1020 + 175, + darmanitangalar: 1020 + 176, + darmanitangalarzen: 1020 + 177, + yamaskgalar: 1020 + 178, + stunfiskgalar: 1020 + 179, + cramorantgulping: 1020 + 180, + cramorantgorging: 1020 + 181, + toxtricitylowkey: 1020 + 182, sinisteaantique: 854, polteageistantique: 855, - alcremierubycream: 900 + 183, - alcremiematchacream: 900 + 184, - alcremiemintcream: 900 + 185, - alcremielemoncream: 900 + 186, - alcremiesaltedcream: 900 + 187, - alcremierubyswirl: 900 + 188, - alcremiecaramelswirl: 900 + 189, - alcremierainbowswirl: 900 + 190, - eiscuenoice: 900 + 191, - indeedeef: 900 + 192, - morpekohangry: 900 + 193, - zaciancrowned: 900 + 194, - zamazentacrowned: 900 + 195, - slowpokegalar: 900 + 196, - slowbrogalar: 900 + 197, - zarudedada: 900 + 198, - pikachuworld: 900 + 199, - articunogalar: 900 + 200, - zapdosgalar: 900 + 201, - moltresgalar: 900 + 202, - slowkinggalar: 900 + 203, - calyrexice: 900 + 204, - calyrexshadow: 900 + 205, + alcremierubycream: 1020 + 183, + alcremiematchacream: 1020 + 184, + alcremiemintcream: 1020 + 185, + alcremielemoncream: 1020 + 186, + alcremiesaltedcream: 1020 + 187, + alcremierubyswirl: 1020 + 188, + alcremiecaramelswirl: 1020 + 189, + alcremierainbowswirl: 1020 + 190, + eiscuenoice: 1020 + 191, + indeedeef: 1020 + 192, + morpekohangry: 1020 + 193, + zaciancrowned: 1020 + 194, + zamazentacrowned: 1020 + 195, + slowpokegalar: 1020 + 196, + slowbrogalar: 1020 + 197, + zarudedada: 1020 + 198, + pikachuworld: 1020 + 199, + articunogalar: 1020 + 200, + zapdosgalar: 1020 + 201, + moltresgalar: 1020 + 202, + slowkinggalar: 1020 + 203, + calyrexice: 1020 + 204, + calyrexshadow: 1020 + 205, + growlithehisui: 1020 + 206, + arcaninehisui: 1020 + 207, + voltorbhisui: 1020 + 208, + electrodehisui: 1020 + 209, + typhlosionhisui: 1020 + 210, + qwilfishhisui: 1020 + 211, + sneaselhisui: 1020 + 212, + samurotthisui: 1020 + 213, + lilliganthisui: 1020 + 214, + zoruahisui: 1020 + 215, + zoroarkhisui: 1020 + 216, + braviaryhisui: 1020 + 217, + sliggoohisui: 1020 + 218, + goodrahisui: 1020 + 219, + avalugghisui: 1020 + 220, + decidueyehisui: 1020 + 221, + basculegionf: 1020 + 222, + enamorustherian: 1020 + 223, + taurospaldea: 1020 + 224, + taurospaldeafire: 1020 + 225, + taurospaldeawater: 1020 + 226, + wooperpaldea: 1020 + 227, + oinkolognef: 1020 + 228, + palafinhero: 1020 + 229, + mausholdfour: 1020 + 230, + tatsugiridroopy: 1020 + 231, + tatsugiristretchy: 1020 + 232, + squawkabillyblue: 1020 + 233, + squawkabillyyellow: 1020 + 234, + squawkabillywhite: 1020 + 235, + gimmighoulroaming: 1020 + 236, gumshoostotem: 735, - raticatealolatotem: 900 + 120, - marowakalolatotem: 900 + 136, + raticatealolatotem: 1020 + 120, + marowakalolatotem: 1020 + 136, araquanidtotem: 752, lurantistotem: 754, salazzletotem: 758, @@ -363,271 +394,271 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { ribombeetotem: 743, kommoototem: 784, - venusaurmega: 1116 + 0, - charizardmegax: 1116 + 1, - charizardmegay: 1116 + 2, - blastoisemega: 1116 + 3, - beedrillmega: 1116 + 4, - pidgeotmega: 1116 + 5, - alakazammega: 1116 + 6, - slowbromega: 1116 + 7, - gengarmega: 1116 + 8, - kangaskhanmega: 1116 + 9, - pinsirmega: 1116 + 10, - gyaradosmega: 1116 + 11, - aerodactylmega: 1116 + 12, - mewtwomegax: 1116 + 13, - mewtwomegay: 1116 + 14, - ampharosmega: 1116 + 15, - steelixmega: 1116 + 16, - scizormega: 1116 + 17, - heracrossmega: 1116 + 18, - houndoommega: 1116 + 19, - tyranitarmega: 1116 + 20, - sceptilemega: 1116 + 21, - blazikenmega: 1116 + 22, - swampertmega: 1116 + 23, - gardevoirmega: 1116 + 24, - sableyemega: 1116 + 25, - mawilemega: 1116 + 26, - aggronmega: 1116 + 27, - medichammega: 1116 + 28, - manectricmega: 1116 + 29, - sharpedomega: 1116 + 30, - cameruptmega: 1116 + 31, - altariamega: 1116 + 32, - banettemega: 1116 + 33, - absolmega: 1116 + 34, - glaliemega: 1116 + 35, - salamencemega: 1116 + 36, - metagrossmega: 1116 + 37, - latiasmega: 1116 + 38, - latiosmega: 1116 + 39, - kyogreprimal: 1116 + 40, - groudonprimal: 1116 + 41, - rayquazamega: 1116 + 42, - lopunnymega: 1116 + 43, - garchompmega: 1116 + 44, - lucariomega: 1116 + 45, - abomasnowmega: 1116 + 46, - gallademega: 1116 + 47, - audinomega: 1116 + 48, - dianciemega: 1116 + 49, - charizardgmax: 1116 + 50, - butterfreegmax: 1116 + 51, - pikachugmax: 1116 + 52, - meowthgmax: 1116 + 53, - machampgmax: 1116 + 54, - gengargmax: 1116 + 55, - kinglergmax: 1116 + 56, - laprasgmax: 1116 + 57, - eeveegmax: 1116 + 58, - snorlaxgmax: 1116 + 59, - garbodorgmax: 1116 + 60, - melmetalgmax: 1116 + 61, - corviknightgmax: 1116 + 62, - orbeetlegmax: 1116 + 63, - drednawgmax: 1116 + 64, - coalossalgmax: 1116 + 65, - flapplegmax: 1116 + 66, - appletungmax: 1116 + 67, - sandacondagmax: 1116 + 68, - toxtricitygmax: 1116 + 69, - toxtricitylowkeygmax: 1116 + 69, - centiskorchgmax: 1116 + 70, - hatterenegmax: 1116 + 71, - grimmsnarlgmax: 1116 + 72, - alcremiegmax: 1116 + 73, - copperajahgmax: 1116 + 74, - duraludongmax: 1116 + 75, - eternatuseternamax: 1116 + 76, - venusaurgmax: 1116 + 77, - blastoisegmax: 1116 + 78, - rillaboomgmax: 1116 + 79, - cinderacegmax: 1116 + 80, - inteleongmax: 1116 + 81, - urshifugmax: 1116 + 82, - urshifurapidstrikegmax: 1116 + 83, + venusaurmega: 1260 + 0, + charizardmegax: 1260 + 1, + charizardmegay: 1260 + 2, + blastoisemega: 1260 + 3, + beedrillmega: 1260 + 4, + pidgeotmega: 1260 + 5, + alakazammega: 1260 + 6, + slowbromega: 1260 + 7, + gengarmega: 1260 + 8, + kangaskhanmega: 1260 + 9, + pinsirmega: 1260 + 10, + gyaradosmega: 1260 + 11, + aerodactylmega: 1260 + 12, + mewtwomegax: 1260 + 13, + mewtwomegay: 1260 + 14, + ampharosmega: 1260 + 15, + steelixmega: 1260 + 16, + scizormega: 1260 + 17, + heracrossmega: 1260 + 18, + houndoommega: 1260 + 19, + tyranitarmega: 1260 + 20, + sceptilemega: 1260 + 21, + blazikenmega: 1260 + 22, + swampertmega: 1260 + 23, + gardevoirmega: 1260 + 24, + sableyemega: 1260 + 25, + mawilemega: 1260 + 26, + aggronmega: 1260 + 27, + medichammega: 1260 + 28, + manectricmega: 1260 + 29, + sharpedomega: 1260 + 30, + cameruptmega: 1260 + 31, + altariamega: 1260 + 32, + banettemega: 1260 + 33, + absolmega: 1260 + 34, + glaliemega: 1260 + 35, + salamencemega: 1260 + 36, + metagrossmega: 1260 + 37, + latiasmega: 1260 + 38, + latiosmega: 1260 + 39, + kyogreprimal: 1260 + 40, + groudonprimal: 1260 + 41, + rayquazamega: 1260 + 42, + lopunnymega: 1260 + 43, + garchompmega: 1260 + 44, + lucariomega: 1260 + 45, + abomasnowmega: 1260 + 46, + gallademega: 1260 + 47, + audinomega: 1260 + 48, + dianciemega: 1260 + 49, + charizardgmax: 1260 + 50, + butterfreegmax: 1260 + 51, + pikachugmax: 1260 + 52, + meowthgmax: 1260 + 53, + machampgmax: 1260 + 54, + gengargmax: 1260 + 55, + kinglergmax: 1260 + 56, + laprasgmax: 1260 + 57, + eeveegmax: 1260 + 58, + snorlaxgmax: 1260 + 59, + garbodorgmax: 1260 + 60, + melmetalgmax: 1260 + 61, + corviknightgmax: 1260 + 62, + orbeetlegmax: 1260 + 63, + drednawgmax: 1260 + 64, + coalossalgmax: 1260 + 65, + flapplegmax: 1260 + 66, + appletungmax: 1260 + 67, + sandacondagmax: 1260 + 68, + toxtricitygmax: 1260 + 69, + toxtricitylowkeygmax: 1260 + 69, + centiskorchgmax: 1260 + 70, + hatterenegmax: 1260 + 71, + grimmsnarlgmax: 1260 + 72, + alcremiegmax: 1260 + 73, + copperajahgmax: 1260 + 74, + duraludongmax: 1260 + 75, + eternatuseternamax: 1260 + 76, + venusaurgmax: 1260 + 77, + blastoisegmax: 1260 + 78, + rillaboomgmax: 1260 + 79, + cinderacegmax: 1260 + 80, + inteleongmax: 1260 + 81, + urshifugmax: 1260 + 82, + urshifurapidstrikegmax: 1260 + 83, - syclant: 1308 + 0, - revenankh: 1308 + 1, - pyroak: 1308 + 2, - fidgit: 1308 + 3, - stratagem: 1308 + 4, - arghonaut: 1308 + 5, - kitsunoh: 1308 + 6, - cyclohm: 1308 + 7, - colossoil: 1308 + 8, - krilowatt: 1308 + 9, - voodoom: 1308 + 10, - tomohawk: 1308 + 11, - necturna: 1308 + 12, - mollux: 1308 + 13, - aurumoth: 1308 + 14, - malaconda: 1308 + 15, - cawmodore: 1308 + 16, - volkraken: 1308 + 17, - plasmanta: 1308 + 18, - naviathan: 1308 + 19, - crucibelle: 1308 + 20, - crucibellemega: 1308 + 21, - kerfluffle: 1308 + 22, - pajantom: 1308 + 23, - jumbao: 1308 + 24, - caribolt: 1308 + 25, - smokomodo: 1308 + 26, - snaelstrom: 1308 + 27, - equilibra: 1308 + 28, - astrolotl: 1308 + 29, - miasmaw: 1308 + 30, - chromera: 1308 + 31, - venomicon: 1308 + 32, - venomiconepilogue: 1308 + 33, - saharaja: 1308 + 34, + syclant: 1452 + 0, + revenankh: 1452 + 1, + pyroak: 1452 + 2, + fidgit: 1452 + 3, + stratagem: 1452 + 4, + arghonaut: 1452 + 5, + kitsunoh: 1452 + 6, + cyclohm: 1452 + 7, + colossoil: 1452 + 8, + krilowatt: 1452 + 9, + voodoom: 1452 + 10, + tomohawk: 1452 + 11, + necturna: 1452 + 12, + mollux: 1452 + 13, + aurumoth: 1452 + 14, + malaconda: 1452 + 15, + cawmodore: 1452 + 16, + volkraken: 1452 + 17, + plasmanta: 1452 + 18, + naviathan: 1452 + 19, + crucibelle: 1452 + 20, + crucibellemega: 1452 + 21, + kerfluffle: 1452 + 22, + pajantom: 1452 + 23, + jumbao: 1452 + 24, + caribolt: 1452 + 25, + smokomodo: 1452 + 26, + snaelstrom: 1452 + 27, + equilibra: 1452 + 28, + astrolotl: 1452 + 29, + miasmaw: 1452 + 30, + chromera: 1452 + 31, + venomicon: 1452 + 32, + venomiconepilogue: 1452 + 33, + saharaja: 1452 + 34, - syclar: 1344 + 0, - embirch: 1344 + 1, - flarelm: 1344 + 2, - breezi: 1344 + 3, - scratchet: 1344 + 4, - necturine: 1344 + 5, - cupra: 1344 + 6, - argalis: 1344 + 7, - brattler: 1344 + 8, - cawdet: 1344 + 9, - volkritter: 1344 + 10, - snugglow: 1344 + 11, - floatoy: 1344 + 12, - caimanoe: 1344 + 13, - pluffle: 1344 + 14, - rebble: 1344 + 15, - tactite: 1344 + 16, - privatyke: 1344 + 17, - nohface: 1344 + 18, - monohm: 1344 + 19, - duohm: 1344 + 20, - protowatt: 1344 + 21, - voodoll: 1344 + 22, - mumbao: 1344 + 23, - fawnifer: 1344 + 24, - electrelk: 1344 + 25, - smogecko: 1344 + 26, - smoguana: 1344 + 27, - swirlpool: 1344 + 28, - coribalis: 1344 + 29, - justyke: 1344 + 30, - solotl: 1344 + 31, - miasmite: 1344 + 32, - dorsoil: 1344 + 33, + syclar: 1488 + 0, + embirch: 1488 + 1, + flarelm: 1488 + 2, + breezi: 1488 + 3, + scratchet: 1488 + 4, + necturine: 1488 + 5, + cupra: 1488 + 6, + argalis: 1488 + 7, + brattler: 1488 + 8, + cawdet: 1488 + 9, + volkritter: 1488 + 10, + snugglow: 1488 + 11, + floatoy: 1488 + 12, + caimanoe: 1488 + 13, + pluffle: 1488 + 14, + rebble: 1488 + 15, + tactite: 1488 + 16, + privatyke: 1488 + 17, + nohface: 1488 + 18, + monohm: 1488 + 19, + duohm: 1488 + 20, + protowatt: 1488 + 21, + voodoll: 1488 + 22, + mumbao: 1488 + 23, + fawnifer: 1488 + 24, + electrelk: 1488 + 25, + smogecko: 1488 + 26, + smoguana: 1488 + 27, + swirlpool: 1488 + 28, + coribalis: 1488 + 29, + justyke: 1488 + 30, + solotl: 1488 + 31, + miasmite: 1488 + 32, + dorsoil: 1488 + 33, }; const BattlePokemonIconIndexesLeft: {[id: string]: number} = { - pikachubelle: 1200 + 0, - pikachupopstar: 1200 + 1, - clefairy: 1200 + 2, - clefable: 1200 + 3, - jigglypuff: 1200 + 4, - wigglytuff: 1200 + 5, - dugtrioalola: 1200 + 6, - poliwhirl: 1200 + 7, - poliwrath: 1200 + 8, - mukalola: 1200 + 9, - kingler: 1200 + 10, - croconaw: 1200 + 11, - cleffa: 1200 + 12, - igglybuff: 1200 + 13, - politoed: 1200 + 14, - unownb: 1200 + 15, - unownc: 1200 + 16, - unownd: 1200 + 17, - unowne: 1200 + 18, - unownf: 1200 + 19, - unowng: 1200 + 20, - unownh: 1200 + 21, - unownj: 1200 + 22, - unownk: 1200 + 23, - unownl: 1200 + 24, - unownm: 1200 + 25, - unownn: 1200 + 26, - unownp: 1200 + 27, - unownq: 1200 + 28, - unownquestion: 1200 + 29, - unownr: 1200 + 30, - unowns: 1200 + 31, - unownt: 1200 + 32, - unownv: 1200 + 33, - unownz: 1200 + 34, - sneasel: 1200 + 35, - teddiursa: 1200 + 36, - roselia: 1200 + 37, - zangoose: 1200 + 38, - seviper: 1200 + 39, - castformsnowy: 1200 + 40, - absolmega: 1200 + 41, - absol: 1200 + 42, - regirock: 1200 + 43, - torterra: 1200 + 44, - budew: 1200 + 45, - roserade: 1200 + 46, - magmortar: 1200 + 47, - togekiss: 1200 + 48, - rotomwash: 1200 + 49, - shayminsky: 1200 + 50, - emboar: 1200 + 51, - pansear: 1200 + 52, - simisear: 1200 + 53, - drilbur: 1200 + 54, - excadrill: 1200 + 55, - sawk: 1200 + 56, - lilligant: 1200 + 57, - garbodor: 1200 + 58, - solosis: 1200 + 59, - vanilluxe: 1200 + 60, - amoonguss: 1200 + 61, - klink: 1200 + 62, - klang: 1200 + 63, - klinklang: 1200 + 64, - litwick: 1200 + 65, - golett: 1200 + 66, - golurk: 1200 + 67, - kyuremblack: 1200 + 68, - kyuremwhite: 1200 + 69, - kyurem: 1200 + 70, - keldeoresolute: 1200 + 71, - meloetta: 1200 + 72, - greninja: 1200 + 73, - greninjaash: 1200 + 74, - furfroudebutante: 1200 + 75, - barbaracle: 1200 + 76, - clauncher: 1200 + 77, - clawitzer: 1200 + 78, - sylveon: 1200 + 79, - klefki: 1200 + 80, - zygarde: 1200 + 81, - zygarde10: 1200 + 82, - zygardecomplete: 1200 + 83, - dartrix: 1200 + 84, - steenee: 1200 + 85, - tsareena: 1200 + 86, - comfey: 1200 + 87, - miniormeteor: 1200 + 88, - minior: 1200 + 89, - miniororange: 1200 + 90, - minioryellow: 1200 + 91, - miniorgreen: 1200 + 92, - miniorblue: 1200 + 93, - miniorviolet: 1200 + 94, - miniorindigo: 1200 + 95, - dhelmise: 1200 + 96, - necrozma: 1200 + 97, - marshadow: 1200 + 98, - pikachuoriginal: 1200 + 99, - pikachupartner: 1200 + 100, - necrozmaduskmane: 1200 + 101, - necrozmadawnwings: 1200 + 102, - necrozmaultra: 1200 + 103, - stakataka: 1200 + 104, - blacephalon: 1200 + 105, + pikachubelle: 1344 + 0, + pikachupopstar: 1344 + 1, + clefairy: 1344 + 2, + clefable: 1344 + 3, + jigglypuff: 1344 + 4, + wigglytuff: 1344 + 5, + dugtrioalola: 1344 + 6, + poliwhirl: 1344 + 7, + poliwrath: 1344 + 8, + mukalola: 1344 + 9, + kingler: 1344 + 10, + croconaw: 1344 + 11, + cleffa: 1344 + 12, + igglybuff: 1344 + 13, + politoed: 1344 + 14, + unownb: 1344 + 15, + unownc: 1344 + 16, + unownd: 1344 + 17, + unowne: 1344 + 18, + unownf: 1344 + 19, + unowng: 1344 + 20, + unownh: 1344 + 21, + unownj: 1344 + 22, + unownk: 1344 + 23, + unownl: 1344 + 24, + unownm: 1344 + 25, + unownn: 1344 + 26, + unownp: 1344 + 27, + unownq: 1344 + 28, + unownquestion: 1344 + 29, + unownr: 1344 + 30, + unowns: 1344 + 31, + unownt: 1344 + 32, + unownv: 1344 + 33, + unownz: 1344 + 34, + sneasel: 1344 + 35, + teddiursa: 1344 + 36, + roselia: 1344 + 37, + zangoose: 1344 + 38, + seviper: 1344 + 39, + castformsnowy: 1344 + 40, + absolmega: 1344 + 41, + absol: 1344 + 42, + regirock: 1344 + 43, + torterra: 1344 + 44, + budew: 1344 + 45, + roserade: 1344 + 46, + magmortar: 1344 + 47, + togekiss: 1344 + 48, + rotomwash: 1344 + 49, + shayminsky: 1344 + 50, + emboar: 1344 + 51, + pansear: 1344 + 52, + simisear: 1344 + 53, + drilbur: 1344 + 54, + excadrill: 1344 + 55, + sawk: 1344 + 56, + lilligant: 1344 + 57, + garbodor: 1344 + 58, + solosis: 1344 + 59, + vanilluxe: 1344 + 60, + amoonguss: 1344 + 61, + klink: 1344 + 62, + klang: 1344 + 63, + klinklang: 1344 + 64, + litwick: 1344 + 65, + golett: 1344 + 66, + golurk: 1344 + 67, + kyuremblack: 1344 + 68, + kyuremwhite: 1344 + 69, + kyurem: 1344 + 70, + keldeoresolute: 1344 + 71, + meloetta: 1344 + 72, + greninja: 1344 + 73, + greninjaash: 1344 + 74, + furfroudebutante: 1344 + 75, + barbaracle: 1344 + 76, + clauncher: 1344 + 77, + clawitzer: 1344 + 78, + sylveon: 1344 + 79, + klefki: 1344 + 80, + zygarde: 1344 + 81, + zygarde10: 1344 + 82, + zygardecomplete: 1344 + 83, + dartrix: 1344 + 84, + steenee: 1344 + 85, + tsareena: 1344 + 86, + comfey: 1344 + 87, + miniormeteor: 1344 + 88, + minior: 1344 + 89, + miniororange: 1344 + 90, + minioryellow: 1344 + 91, + miniorgreen: 1344 + 92, + miniorblue: 1344 + 93, + miniorviolet: 1344 + 94, + miniorindigo: 1344 + 95, + dhelmise: 1344 + 96, + necrozma: 1344 + 97, + marshadow: 1344 + 98, + pikachuoriginal: 1344 + 99, + pikachupartner: 1344 + 100, + necrozmaduskmane: 1344 + 101, + necrozmadawnwings: 1344 + 102, + necrozmaultra: 1344 + 103, + stakataka: 1344 + 104, + blacephalon: 1344 + 105, }; const BattleAvatarNumbers: {[k: string]: string} = { @@ -1426,7 +1457,9 @@ class Species implements Effect { this.unreleasedHidden = data.unreleasedHidden || false; this.changesFrom = data.changesFrom || undefined; if (!this.gen) { - if (this.num >= 810 || this.formeid.startsWith('-galar')) { + if (this.num >= 906 || this.formeid.startsWith('-paldea')) { + this.gen = 9; + } else if (this.num >= 810 || this.formeid.startsWith('-galar') || this.formeid.startsWith('-hisui')) { this.gen = 8; } else if (this.num >= 722 || this.formeid === '-alola' || this.formeid === '-starter') { this.gen = 7; diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 6cc032e059..889a589027 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -358,7 +358,7 @@ class DexSearch { // For pokemon queries, accept types/tier/abilities/moves/eggroups as filters if (searchType === 'pokemon' && (typeIndex === 5 || typeIndex > 7)) continue; - if (searchType === 'pokemon' && typeIndex === 3 && this.dex.gen < 8) continue; + if (searchType === 'pokemon' && typeIndex === 3 && this.dex.gen < 9) continue; // For move queries, accept types/categories as filters if (searchType === 'move' && ((typeIndex !== 8 && typeIndex > 4) || typeIndex === 3)) continue; // For move queries in the teambuilder, don't accept pokemon as filters @@ -757,7 +757,9 @@ abstract class BattleTypedSearch { this.format.startsWith('battlestadium') || this.format.startsWith('battlefestival') ) { - if (gen === 8) { + if (gen === 9) { + genChar = 'a'; + } else if (gen === 8) { genChar = 'g'; } else if (gen === 7) { genChar = 'q'; @@ -793,7 +795,7 @@ abstract class BattleTypedSearch { this.formatType === 'nfe' ? `gen${gen}nfe` : this.formatType === 'dlc1' ? 'gen8dlc1' : this.formatType === 'dlc1doubles' ? 'gen8dlc1doubles' : - this.formatType === 'natdex' ? 'natdex' : + this.formatType === 'natdex' ? `gen${gen}natdex` : this.formatType === 'stadium' ? `gen${gen}stadium${gen > 1 ? gen : ''}` : `gen${gen}`; if (table && table[tableKey]) { @@ -855,6 +857,9 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { case 'grookey': results.push(['header', "Generation 8"]); break; + case 'sprigatito': + results.push(['header', "Generation 9"]); + break; case 'missingno': results.push(['header', "Glitch"]); break; @@ -876,7 +881,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { const dex = this.dex; let table = BattleTeambuilderTable; - if ((format.endsWith('cap') || format.endsWith('caplc')) && dex.gen < 8) { + if ((format.endsWith('cap') || format.endsWith('caplc')) && dex.gen < 9) { table = table['gen' + dex.gen]; } else if (isVGCOrBS) { table = table['gen' + dex.gen + 'vgc']; @@ -890,14 +895,14 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { ) { table = table['gen' + dex.gen + 'doubles']; isDoublesOrBS = true; - } else if (dex.gen < 8 && !this.formatType) { + } else if (dex.gen < 9 && !this.formatType) { table = table['gen' + dex.gen]; } else if (this.formatType?.startsWith('bdsp')) { table = table['gen8' + this.formatType]; } else if (this.formatType === 'letsgo') { table = table['gen7letsgo']; } else if (this.formatType === 'natdex') { - table = table['natdex']; + table = table['gen' + this.dex.gen + 'natdex']; } else if (this.formatType === 'metronome') { table = table['metronome']; } else if (this.formatType === 'nfe') { @@ -1141,10 +1146,10 @@ class BattleItemSearch extends BattleTypedSearch<'item'> { if (this.formatType?.startsWith('bdsp')) { table = table['gen8bdsp']; } else if (this.formatType === 'natdex') { - table = table['natdex']; + table = table['gen' + this.dex.gen + 'natdex']; } else if (this.formatType === 'metronome') { table = table['metronome']; - } else if (this.dex.gen < 8) { + } else if (this.dex.gen < 9) { table = table['gen' + this.dex.gen]; } if (!table.itemSet) { @@ -1431,7 +1436,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { const isSTABmons = (format.includes('stabmons') || format === 'staaabmons'); const isTradebacks = format.includes('tradebacks'); const regionBornLegality = dex.gen >= 6 && - /^battle(spot|stadium|festival)/.test(format) || format.startsWith('vgc'); + /^battle(spot|stadium|festival)/.test(format) || format.startsWith('vgc') || + (dex.gen === 9 && this.formatType !== 'natdex'); const abilityid = this.set ? toID(this.set.ability) : '' as ID; const itemid = this.set ? toID(this.set.item) : '' as ID; @@ -1451,7 +1457,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { for (let moveid in learnset) { let learnsetEntry = learnset[moveid]; const move = dex.moves.get(moveid); - const minGenCode: {[gen: number]: string} = {6: 'p', 7: 'q', 8: 'g'}; + const minGenCode: {[gen: number]: string} = {6: 'p', 7: 'q', 8: 'g', 9: 'a'}; if (regionBornLegality && !learnsetEntry.includes(minGenCode[dex.gen])) { continue; } @@ -1528,7 +1534,9 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { if (pokemon.battleOnly && typeof pokemon.battleOnly === 'string') { species = dex.species.get(pokemon.battleOnly); } - const excludedForme = (s: Species) => ['Alola', 'Alola-Totem', 'Galar', 'Galar-Zen', 'Hisui'].includes(s.forme); + const excludedForme = (s: Species) => [ + 'Alola', 'Alola-Totem', 'Galar', 'Galar-Zen', 'Hisui', 'Paldea', + ].includes(s.forme); if (baseSpecies.otherFormes && !['Wormadam', 'Urshifu'].includes(baseSpecies.baseSpecies)) { if (!excludedForme(species)) speciesTypes.push(...baseSpecies.types); for (const formeName of baseSpecies.otherFormes) { diff --git a/src/battle-dex.ts b/src/battle-dex.ts index c9de9c3c5f..9b80111a81 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -170,8 +170,8 @@ interface TeambuilderSpriteData { } const Dex = new class implements ModdedDex { - readonly gen = 8; - readonly modid = 'gen8' as ID; + readonly gen = 9; + readonly modid = 'gen9' as ID; readonly cache = null!; readonly statNames: ReadonlyArray = ['hp', 'atk', 'def', 'spa', 'spd', 'spe']; @@ -194,7 +194,7 @@ const Dex = new class implements ModdedDex { moddedDexes: {[mod: string]: ModdedDex} = {}; mod(modid: ID): ModdedDex { - if (modid === 'gen8') return this; + if (modid === 'gen9') return this; if (!window.BattleTeambuilderTable) return this; if (modid in this.moddedDexes) { return this.moddedDexes[modid]; @@ -543,7 +543,7 @@ const Dex = new class implements ModdedDex { if (Dex.prefs('nopastgens')) graphicsGen = 6; if (Dex.prefs('bwgfx') && graphicsGen >= 6) graphicsGen = 5; spriteData.gen = Math.max(graphicsGen, Math.min(species.gen, 5)); - const baseDir = ['', 'gen1', 'gen2', 'gen3', 'gen4', 'gen5', '', '', ''][spriteData.gen]; + const baseDir = ['', 'gen1', 'gen2', 'gen3', 'gen4', 'gen5', '', '', '', ''][spriteData.gen]; let animationData = null; let miscData = null; @@ -680,7 +680,7 @@ const Dex = new class implements ModdedDex { num = BattlePokedex[id].num; } if (num < 0) num = 0; - if (num > 898) num = 0; + if (num > 1010) num = 0; if (window.BattlePokemonIconIndexes?.[id]) { num = BattlePokemonIconIndexes[id]; @@ -790,7 +790,7 @@ const Dex = new class implements ModdedDex { let top = Math.floor(num / 16) * 24; let left = (num % 16) * 24; - return 'background:transparent url(' + Dex.resourcePrefix + 'sprites/itemicons-sheet.png?g8) no-repeat scroll -' + left + 'px -' + top + 'px'; + return 'background:transparent url(' + Dex.resourcePrefix + 'sprites/itemicons-sheet.png?g9) no-repeat scroll -' + left + 'px -' + top + 'px'; } getTypeIcon(type: string | null, b?: boolean) { // b is just for utilichart.js @@ -889,7 +889,7 @@ class ModdedDex { let data = {...Dex.items.get(name)}; - for (let i = this.gen; i < 8; i++) { + for (let i = this.gen; i < 9; i++) { const table = window.BattleTeambuilderTable['gen' + i]; if (id in table.overrideItemDesc) { data.shortDesc = table.overrideItemDesc[id]; diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 63c93c10e7..fc9013a8b8 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -20,7 +20,7 @@ class BattleTextParser { p3 = "Player 3"; p4 = "Player 4"; perspective: SideID; - gen = 7; + gen = 9; turn = 0; curLineSection: 'break' | 'preMajor' | 'major' | 'postMajor' = 'break'; lowercaseRegExp: RegExp | null | undefined = undefined; @@ -358,7 +358,8 @@ class BattleTextParser { switch (cmd) { case 'done' : case 'turn': return 'break'; - case 'move' : case 'cant': case 'switch': case 'drag': case 'upkeep': case 'start': case '-mega': case '-candynamax': + case 'move' : case 'cant': case 'switch': case 'drag': case 'upkeep': case 'start': + case '-mega': case '-candynamax': case '-terastallize': return 'major'; case 'switchout': case 'faint': return 'preMajor'; @@ -584,6 +585,11 @@ class BattleTextParser { const template = this.template('activate', 'perishsong'); return line1 + template.replace('[POKEMON]', this.pokemon(pokemon)).replace('[NUMBER]', num); } + if (id.startsWith('protosynthesis') || id.startsWith('quarkdrive')) { + const stat = id.slice(-3); + const template = this.template('start', id.slice(0, id.length - 3)); + return line1 + template.replace('[POKEMON]', this.pokemon(pokemon)).replace('[STAT]', BattleTextParser.stat(stat)); + } let templateId = 'start'; if (kwArgs.already) templateId = 'alreadyStarted'; if (kwArgs.fatigue) templateId = 'startFromFatigue'; @@ -782,6 +788,9 @@ class BattleTextParser { return this.template('upkeep', weather, 'NODEFAULT'); } const line1 = this.maybeAbility(kwArgs.from, kwArgs.of); + if (BattleTextParser.effectId(kwArgs.from) === 'orichalcumpulse') { + return line1 + this.template('start', 'orichalcumpulse').replace('[POKEMON]', this.pokemon(kwArgs.of)); + } let template = this.template('start', weather, 'NODEFAULT'); if (!template) template = this.template('startFieldEffect').replace('[EFFECT]', this.effect(weather)); return line1 + template; @@ -790,6 +799,9 @@ class BattleTextParser { case '-fieldstart': case '-fieldactivate': { const [, effect] = args; const line1 = this.maybeAbility(kwArgs.from, kwArgs.of); + if (BattleTextParser.effectId(kwArgs.from) === 'hadronengine') { + return line1 + this.template('start', 'hadronengine').replace('[POKEMON]', this.pokemon(kwArgs.of)); + } let templateId = cmd.slice(6); if (BattleTextParser.effectId(effect) === 'perishsong') templateId = 'start'; let template = this.template(templateId, effect, 'NODEFAULT'); @@ -838,10 +850,10 @@ class BattleTextParser { return line1 + template.replace('[POKEMON]', this.pokemon(kwArgs.of)).replace('[SOURCE]', this.pokemon(pokemon)); } - if (id === 'mummy' && kwArgs.ability) { + if ((id === 'mummy' || id === 'lingeringaroma') && kwArgs.ability) { line1 += this.ability(kwArgs.ability, target); - line1 += this.ability('Mummy', target); - const template = this.template('changeAbility', 'mummy'); + line1 += this.ability(id === 'mummy' ? 'Mummy' : 'Lingering Aroma', target); + const template = this.template('changeAbility', id); return line1 + template.replace('[TARGET]', this.pokemon(target)); } @@ -849,6 +861,9 @@ class BattleTextParser { if (id === 'forewarn' && pokemon === target) { templateId = 'activateNoTarget'; } + if ((id === 'protosynthesis' || id === 'quarkdrive') && kwArgs.fromitem) { + templateId = 'activateFromItem'; + } let template = this.template(templateId, effect, 'NODEFAULT'); if (!template) { if (line1) return line1; // Abilities don't have a default template @@ -1011,7 +1026,7 @@ class BattleTextParser { const line1 = this.maybeAbility(kwArgs.from, kwArgs.of || pokemon); let templateId = 'block'; if (['desolateland', 'primordialsea'].includes(blocker) && - !['sunnyday', 'raindance', 'sandstorm', 'hail'].includes(id)) { + !['sunnyday', 'raindance', 'sandstorm', 'hail', 'snow'].includes(id)) { templateId = 'blockMove'; } else if (blocker === 'uproar' && kwArgs.msg) { templateId = 'blockSelf'; @@ -1087,6 +1102,15 @@ class BattleTextParser { return template.replace('[POKEMON]', pokemonName).replace('[ITEM]', item).replace('[TRAINER]', this.trainer(side)); } + case '-terastallize': { + const [, pokemon, type] = args; + let id = ''; + let templateId = cmd.slice(1); + let template = this.template(templateId, id); + const pokemonName = this.pokemon(pokemon); + return template.replace('[POKEMON]', pokemonName).replace('[TYPE]', type); + } + case '-zpower': { const [, pokemon] = args; const template = this.template('zPower'); diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 1f91cb1e1d..776efda76e 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -574,6 +574,7 @@ class BattleTooltips { zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Rock']); break; case 'hail': + case 'snow': zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Ice']); break; } @@ -1087,7 +1088,7 @@ class BattleTooltips { if (ability === 'sandrush' && weather === 'sandstorm') { speedModifiers.push(2); } - if (ability === 'slushrush' && weather === 'hail') { + if (ability === 'slushrush' && (weather === 'hail' || weather === 'snow')) { speedModifiers.push(2); } if (item !== 'utilityumbrella') { @@ -1378,6 +1379,7 @@ class BattleTooltips { moveType = 'Rock'; break; case 'hail': + case 'snow': moveType = 'Ice'; break; } @@ -1451,6 +1453,7 @@ class BattleTooltips { } if (move.id === 'blizzard') { value.weatherModify(0, 'Hail'); + value.weatherModify(0, 'Snow'); } if (move.id === 'hurricane' || move.id === 'thunder') { value.weatherModify(0, 'Rain Dance'); @@ -2107,6 +2110,8 @@ interface PokemonSet { dynamaxLevel?: number; /** Defaults to no (can only be yes for certain Pokemon) */ gigantamax?: boolean; + /** Defaults to the primary type */ + teraType?: string; } class BattleStatGuesser { diff --git a/src/battle.ts b/src/battle.ts index 4909fc63a7..7e2d96b42c 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -90,6 +90,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { itemEffect = ''; prevItem = ''; prevItemEffect = ''; + teraType = ''; boosts: {[stat: string]: number} = {}; status: StatusName | 'tox' | '' | '???' = ''; @@ -428,12 +429,13 @@ export class Pokemon implements PokemonDetails, PokemonHealth { /** * copyAll = false means Baton Pass, * copyAll = true means Illusion breaking + * copyAll = 'shedtail' means Shed Tail */ - copyVolatileFrom(pokemon: Pokemon, copyAll?: boolean) { + copyVolatileFrom(pokemon: Pokemon, copySource?: | 'shedtail' | boolean) { this.boosts = pokemon.boosts; this.volatiles = pokemon.volatiles; // this.lastMove = pokemon.lastMove; // I think - if (!copyAll) { + if (!copySource) { delete this.volatiles['airballoon']; delete this.volatiles['attract']; delete this.volatiles['autotomize']; @@ -455,8 +457,16 @@ export class Pokemon implements PokemonDetails, PokemonHealth { delete this.volatiles['typechange']; delete this.volatiles['yawn']; } + if (copySource === 'shedtail') { + for (let i in this.volatiles) { + if (i === 'substitute') continue; + delete this.volatiles[i]; + } + this.boosts = {}; + } delete this.volatiles['transform']; delete this.volatiles['formechange']; + delete this.volatiles['terastallize']; pokemon.boosts = {}; pokemon.volatiles = {}; @@ -817,8 +827,8 @@ export class Side { pokemon.clearVolatile(); pokemon.lastMove = ''; this.battle.lastMove = 'switch-in'; - if (['batonpass', 'zbatonpass'].includes(this.lastPokemon?.lastMove!)) { - pokemon.copyVolatileFrom(this.lastPokemon!); + if (['batonpass', 'zbatonpass', 'shedtail'].includes(this.lastPokemon?.lastMove!)) { + pokemon.copyVolatileFrom(this.lastPokemon!, this.lastPokemon!.lastMove! === 'shedtail' ? 'shedtail' : false); } this.battle.scene.animSummon(pokemon, slot); @@ -867,14 +877,14 @@ export class Side { this.battle.scene.animSummon(pokemon, slot, true); } switchOut(pokemon: Pokemon, kwArgs: KWArgs, slot = pokemon.slot) { - if (pokemon.lastMove !== 'batonpass' && pokemon.lastMove !== 'zbatonpass') { + if (!['batonpass', 'zbatonpass', 'shedtail'].includes(pokemon.lastMove)) { pokemon.clearVolatile(); } else { pokemon.removeVolatile('transform' as ID); pokemon.removeVolatile('formechange' as ID); } const effect = Dex.getEffect(kwArgs.from); - if (!['batonpass', 'zbatonpass', 'teleport'].includes(effect.id)) { + if (!['batonpass', 'zbatonpass', 'shedtail', 'teleport'].includes(effect.id)) { this.battle.log(['switchout', pokemon.ident], {from: effect.id}); } pokemon.statusData.toxicTurns = 0; @@ -2351,7 +2361,9 @@ export class Battle { poke.details = args[2]; poke.searchid = args[1].substr(0, 2) + args[1].substr(3) + '|' + args[2]; - this.scene.animTransform(poke, true, true); + if (poke.getSpeciesForme() !== 'Palafin-Hero') { + this.scene.animTransform(poke, true, true); + } this.log(args, kwArgs); break; } @@ -2416,6 +2428,14 @@ export class Battle { this.log(args, kwArgs); break; } + case '-terastallize': { + let poke = this.getPokemon(args[1])!; + let type = Dex.types.get(args[2]).name; + poke.teraType = type; + this.scene.animTransform(poke, true, true); + this.log(args, kwArgs); + break; + } case '-start': { let poke = this.getPokemon(args[1])!; let effect = Dex.getEffect(args[2]); @@ -2653,6 +2673,20 @@ export class Battle { poke.removeVolatile('stockpile2' as ID); poke.removeVolatile('stockpile3' as ID); break; + case 'protosynthesis': + poke.removeVolatile('protosynthesisatk' as ID); + poke.removeVolatile('protosynthesisdef' as ID); + poke.removeVolatile('protosynthesisspa' as ID); + poke.removeVolatile('protosynthesisspd' as ID); + poke.removeVolatile('protosynthesisspe' as ID); + break; + case 'quarkdrive': + poke.removeVolatile('quarkdriveatk' as ID); + poke.removeVolatile('quarkdrivedef' as ID); + poke.removeVolatile('quarkdrivespa' as ID); + poke.removeVolatile('quarkdrivespd' as ID); + poke.removeVolatile('quarkdrivespe' as ID); + break; default: if (effect.effectType === 'Move') { if (effect.name === 'Doom Desire') { @@ -2818,6 +2852,10 @@ export class Battle { break; // ability activations + case 'electromorphosis': + case 'windpower': + poke.addMovestatus('charge' as ID); + break; case 'forewarn': if (target) { target.rememberMove(kwArgs.move, 0); @@ -2831,13 +2869,14 @@ export class Battle { } } break; + case 'lingeringaroma': case 'mummy': if (!kwArgs.ability) break; // if Mummy activated but failed, no ability will have been sent let ability = Dex.abilities.get(kwArgs.ability); this.activateAbility(target, ability.name); - this.activateAbility(poke, "Mummy"); + this.activateAbility(poke, effect.name); this.scene.wait(700); - this.activateAbility(target, "Mummy", true); + this.activateAbility(target, effect.name, true); break; // item activations diff --git a/src/panel-teamdropdown.tsx b/src/panel-teamdropdown.tsx index 733f491c9e..0794f16cab 100644 --- a/src/panel-teamdropdown.tsx +++ b/src/panel-teamdropdown.tsx @@ -826,7 +826,7 @@ class FormatDropdownPanel extends PSRoomPanel { {columns.map(column =>
        {column.map(format => format.id ? (
      • ) : (
      • diff --git a/style/battle.css b/style/battle.css index e9fb9e97e8..19458f93b7 100644 --- a/style/battle.css +++ b/style/battle.css @@ -438,6 +438,7 @@ License: GPLv2 background: #E6E0AC url(../fx/weather-sandstorm.png) no-repeat scroll left top; color: #554433; } +.snowweather, .hailweather { background: #AADDEE url(../fx/weather-hail.png) no-repeat scroll left top; color: #114455; From 87f97d5f35a0704192e163b5f068828d28a5dc5d Mon Sep 17 00:00:00 2001 From: Marty-D Date: Thu, 17 Nov 2022 21:21:34 -0500 Subject: [PATCH 322/770] Cachebust the correct sheet --- src/battle-dex.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 9b80111a81..7799ef97db 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -726,7 +726,7 @@ const Dex = new class implements ModdedDex { let top = Math.floor(num / 12) * 30; let left = (num % 12) * 40; let fainted = ((pokemon as Pokemon | ServerPokemon)?.fainted ? `;opacity:.3;filter:grayscale(100%) brightness(.5)` : ``); - return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v8) no-repeat scroll -${left}px -${top}px${fainted}`; + return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v9) no-repeat scroll -${left}px -${top}px${fainted}`; } getTeambuilderSpriteData(pokemon: any, gen: number = 0): TeambuilderSpriteData { From 4667d4d811e4b684b0633106128f4572e2bbb834 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Thu, 17 Nov 2022 19:28:48 -0700 Subject: [PATCH 323/770] Fix some minor Gen 9 bugs (#2012) --- js/client-teambuilder.js | 6 +++--- js/storage.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index a67968439d..0160201d3a 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -2050,15 +2050,15 @@ } } - var generationNumber = 8; + var generationNumber = 9; if (format.substr(0, 3) === 'gen') { var number = parseInt(format.charAt(3), 10); - if (1 <= number && number <= 7) { + if (1 <= number && number <= 8) { generationNumber = number; } format = format.substr(4); } - var generation = ['rb', 'gs', 'rs', 'dp', 'bw', 'xy', 'sm', 'ss'][generationNumber - 1]; + var generation = ['rb', 'gs', 'rs', 'dp', 'bw', 'xy', 'sm', 'ss', 'sv'][generationNumber - 1]; if (format === 'battlespotdoubles') { smogdexid += '/vgc15'; } else if (format === 'doublesou' || format === 'doublesuu') { diff --git a/js/storage.js b/js/storage.js index f075b4f50e..6fd23a3d29 100644 --- a/js/storage.js +++ b/js/storage.js @@ -1196,8 +1196,8 @@ Storage.importTeam = function (buffer, teams) { } else if (line.substr(0, 14) === 'Hidden Power: ') { line = line.substr(14); curSet.hpType = line; - } else if (line.substr(0, 15) === 'Terastal Type: ') { - line = line.substr(15); + } else if (line.substr(0, 11) === 'Tera Type: ') { + line = line.substr(11); curSet.teraType = line; } else if (line.substr(0, 15) === 'Dynamax Level: ') { line = line.substr(15); @@ -1330,7 +1330,7 @@ Storage.exportTeam = function (team) { text += 'Gigantamax: Yes \n'; } if (curSet.teraType) { - text += 'Terastal Type: ' + curSet.teraType + " \n"; + text += 'Tera Type: ' + curSet.teraType + " \n"; } var first = true; if (curSet.evs) { From 2181a68b7b84e2708dfcacc1e95b032a41719d5a Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Thu, 17 Nov 2022 20:20:49 -0700 Subject: [PATCH 324/770] Teambuilder: Don't search Pokemon that don't learn moves (#2013) --- src/battle-dex-search.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 889a589027..1b084ef3ca 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -755,7 +755,8 @@ abstract class BattleTypedSearch { this.format.startsWith('vgc') || this.format.startsWith('battlespot') || this.format.startsWith('battlestadium') || - this.format.startsWith('battlefestival') + this.format.startsWith('battlefestival') || + (this.dex.gen === 9 && this.formatType !== 'natdex') ) { if (gen === 9) { genChar = 'a'; From 4d92895c87ccc88435be1ff7e4abb8bf3bbff305 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 17 Nov 2022 22:41:23 -0500 Subject: [PATCH 325/770] Change default format to gen9 (#2014) --- js/client-teambuilder.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 0160201d3a..bde4cc8da8 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -126,7 +126,7 @@ // format // Special values: // '' - show all - // 'gen8' - show teams with no format + // 'gen9' - show teams with no format // '/' - show teams with no folder curFolder: '', curFolderKeep: '', @@ -237,7 +237,7 @@ format = this.curFolder; } else { format = Storage.teams[i].format; - if (!format) format = 'gen8'; + if (!format) format = 'gen9'; } if (!format) continue; if (format in folderTable) continue; @@ -250,8 +250,8 @@ } continue; } - if (format === 'gen8') { - folders.push('B~'); + if (format === 'gen9') { + folders.push('A~'); continue; } switch (format.slice(0, 4)) { @@ -367,7 +367,7 @@ var newTeamButtonText = "New Team"; if (filterFolder) newTeamButtonText = "New Team in folder"; - if (filterFormat && filterFormat !== 'gen8') { + if (filterFormat && filterFormat !== 'gen9') { newTeamButtonText = "New " + BattleLog.escapeFormat(filterFormat) + " Team"; } buf += '

        ' + @@ -410,7 +410,7 @@ continue; } - if (filterFormat && filterFormat !== (team.format || 'gen8')) continue; + if (filterFormat && filterFormat !== (team.format || 'gen9')) continue; if (filterFolder !== undefined && filterFolder !== team.folder) continue; if (this.curSearchVal) { @@ -790,11 +790,11 @@ iconCache: '' }; } else { - var format = this.curFolder || 'gen8'; + var format = this.curFolder || 'gen9'; var folder = ''; if (format && format.charAt(format.length - 1) === '/') { folder = format.slice(0, -1); - format = 'gen8'; + format = 'gen9'; } newTeam = { name: (isBox ? 'Box ' : 'Untitled ') + (teams.length + 1), @@ -836,7 +836,7 @@ document.getElementById("pasteData").value = team; document.getElementById("pasteTitle").value = this.curTeam.name; document.getElementById("pasteAuthor").value = app.user.get('name'); - if (this.curTeam.format !== 'gen8') document.getElementById("pasteNotes").value = "Format: " + this.curTeam.format; + if (this.curTeam.format !== 'gen9') document.getElementById("pasteNotes").value = "Format: " + this.curTeam.format; document.getElementById("pokepasteForm").submit(); }, @@ -1959,7 +1959,7 @@ this.$chart.scrollTop(0); } this.search.$inputEl = $inputEl; - this.search.setType(type, this.curTeam.format || 'gen8', this.curSet, cur); + this.search.setType(type, this.curTeam.format || 'gen9', this.curSet, cur); this.qInitial = q; this.search.qName = this.curChartName; if (wasIncomplete) { From 4af200ca891e61ae33e78752963eaf79f1bc6fce Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 17 Nov 2022 22:41:47 -0500 Subject: [PATCH 326/770] Fix Palafin sprite not changing after Zero to Hero (#2015) --- src/battle.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/battle.ts b/src/battle.ts index 7e2d96b42c..64631218e5 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2361,7 +2361,13 @@ export class Battle { poke.details = args[2]; poke.searchid = args[1].substr(0, 2) + args[1].substr(3) + '|' + args[2]; - if (poke.getSpeciesForme() !== 'Palafin-Hero') { + if (poke.getSpeciesForme() === 'Palafin-Hero') { + poke.sprite.sp = Dex.getSpriteData(poke, poke.sprite.isFrontSprite, { + gen: poke.sprite.scene.gen, + mod: poke.sprite.scene.mod, + }); + poke.sprite.oldsp = null; + } else { this.scene.animTransform(poke, true, true); } this.log(args, kwArgs); From 8b5ef7a47d39e3da563c45929f69791d992ab99d Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Fri, 18 Nov 2022 06:40:16 -0700 Subject: [PATCH 327/770] Teambuilder: Include all Paldea formes for STABmons (#2016) --- src/battle-dex-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index 1b084ef3ca..fbe904b754 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1536,7 +1536,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { species = dex.species.get(pokemon.battleOnly); } const excludedForme = (s: Species) => [ - 'Alola', 'Alola-Totem', 'Galar', 'Galar-Zen', 'Hisui', 'Paldea', + 'Alola', 'Alola-Totem', 'Galar', 'Galar-Zen', 'Hisui', 'Paldea', 'Paldea-Fire', 'Paldea-Water', ].includes(s.forme); if (baseSpecies.otherFormes && !['Wormadam', 'Urshifu'].includes(baseSpecies.baseSpecies)) { if (!excludedForme(species)) speciesTypes.push(...baseSpecies.types); From 7fbfc192d4f2896db6d7505132ec279bcc8dcdfa Mon Sep 17 00:00:00 2001 From: Andrew Werner Date: Fri, 18 Nov 2022 14:36:39 -0500 Subject: [PATCH 328/770] Fix Commander Soft-Lock --- js/client-battle.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/client-battle.js b/js/client-battle.js index 25802bf669..c96aee5945 100644 --- a/js/client-battle.js +++ b/js/client-battle.js @@ -518,7 +518,7 @@ if (type !== 'movetarget') { while ( switchables[this.choice.choices.length] && - (switchables[this.choice.choices.length].fainted || switchables[this.choice.choices.length].commanding) && + switchables[this.choice.choices.length].fainted && this.choice.choices.length + 1 < this.battle.nearSide.active.length ) { this.choice.choices.push('pass'); @@ -1320,7 +1320,9 @@ return true; } } else if (this.request.requestType === 'move') { - while (choices.length < this.battle.pokemonControlled && !nearActive[choices.length]) { + var requestDetails = this.request && this.request.side ? this.battle.myPokemon : []; + while (choices.length < this.battle.pokemonControlled && + (!nearActive[choices.length] || requestDetails[choices.length].commanding)) { choices.push('pass'); } From 683dbc52abbd1da43ef81f1b03a3baae7ef81e14 Mon Sep 17 00:00:00 2001 From: Andrew Werner Date: Fri, 18 Nov 2022 18:22:03 -0500 Subject: [PATCH 329/770] Fix Commander when Tatsugiri is in Slot 1 --- js/client-battle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-battle.js b/js/client-battle.js index c96aee5945..b6be21108e 100644 --- a/js/client-battle.js +++ b/js/client-battle.js @@ -518,7 +518,7 @@ if (type !== 'movetarget') { while ( switchables[this.choice.choices.length] && - switchables[this.choice.choices.length].fainted && + (switchables[this.choice.choices.length].fainted || switchables[this.choice.choices.length].commanding) && this.choice.choices.length + 1 < this.battle.nearSide.active.length ) { this.choice.choices.push('pass'); From 8fa4bb7092d8366408d0bc85b979e2de0c21adf7 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sun, 20 Nov 2022 16:28:01 -0700 Subject: [PATCH 330/770] Delete Pokemon-Showdown-Dex submodule (#2019) --- Pokemon-Showdown-Dex | 1 - 1 file changed, 1 deletion(-) delete mode 160000 Pokemon-Showdown-Dex diff --git a/Pokemon-Showdown-Dex b/Pokemon-Showdown-Dex deleted file mode 160000 index c1f0abb5b3..0000000000 --- a/Pokemon-Showdown-Dex +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c1f0abb5b3b37d84b17585e7361e4245418a3db5 From cbd47f4c4e36c91ae6da6ab59f545514d1182cb1 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 21 Nov 2022 11:27:06 -0500 Subject: [PATCH 331/770] Always show Tera Type in details cell (#2017) --- js/client-teambuilder.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index bde4cc8da8..9d7fc5e998 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -1231,9 +1231,7 @@ } } if (this.curTeam.gen === 9) { - if (set.teraType) { - buf += '' + (set.teraType || species.types[0]) + ''; - } + buf += '' + (set.teraType || species.types[0]) + ''; } } buf += ''; @@ -2675,11 +2673,11 @@ } if (this.curTeam.gen === 9) { - buf += '

        '; var types = Dex.types.all(); + var teraType = set.teraType || species.types[0]; for (var i = 0; i < types.length; i++) { - buf += ''; + buf += ''; } buf += '
        '; } @@ -2758,9 +2756,9 @@ delete set.hpType; } - // Terastal type + // Tera type var teraType = this.$chart.find('select[name=teratype]').val(); - if (Dex.types.isName(teraType)) { + if (Dex.types.isName(teraType) && teraType !== species.types[0]) { set.teraType = teraType; } else { delete set.teraType; From 239c1ca9db2498499cb32b0575891693ed4f8305 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 21 Nov 2022 11:27:26 -0500 Subject: [PATCH 332/770] Fix incorrect text for Armor Tail (#2018) --- src/battle-text-parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index fc9013a8b8..672f8c10e2 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -176,7 +176,7 @@ class BattleTextParser { case 'cant': { let [, pokemon, effect, move] = args; - if (['ability: Queenly Majesty', 'ability: Damp', 'ability: Dazzling'].includes(effect)) { + if (['ability: Damp', 'ability: Dazzling', 'ability: Queenly Majesty', 'ability: Armor Tail'].includes(effect)) { args[0] = '-block'; return {args: ['-block', pokemon, effect, move, kwArgs.of], kwArgs: {}}; } From a006a965148a1e01ef4551206dadeac9565218ee Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 21 Nov 2022 11:28:00 -0500 Subject: [PATCH 333/770] Ensure only Psych Up copies volatiles with -copyboost (#2020) --- src/battle.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index 64631218e5..debc2f21a9 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1843,13 +1843,14 @@ export class Battle { case '-copyboost': { let poke = this.getPokemon(args[1])!; let frompoke = this.getPokemon(args[2])!; + let effect = Dex.getEffect(kwArgs.from); let stats = args[3] ? args[3].split(', ') : ['atk', 'def', 'spa', 'spd', 'spe', 'accuracy', 'evasion']; for (const stat of stats) { poke.boosts[stat] = frompoke.boosts[stat]; if (!poke.boosts[stat]) delete poke.boosts[stat]; } - if (this.gen >= 6) { - const volatilesToCopy = ['focusenergy', 'laserfocus']; + if (this.gen >= 6 && effect.id === 'psychup') { + const volatilesToCopy = ['focusenergy', 'gmaxchistrike', 'laserfocus']; for (const volatile of volatilesToCopy) { if (frompoke.volatiles[volatile]) { poke.addVolatile(volatile as ID); From 5facf5ac9df06171ca56c4119b41177f45113d50 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 21 Nov 2022 11:31:44 -0500 Subject: [PATCH 334/770] Check [from] effect for switches instead of lastMove (#2021) --- src/battle.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index debc2f21a9..47404217bf 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -821,14 +821,15 @@ export class Side { return poke; } - switchIn(pokemon: Pokemon, slot = pokemon.slot) { + switchIn(pokemon: Pokemon, kwArgs: KWArgs, slot = pokemon.slot) { this.active[slot] = pokemon; pokemon.slot = slot; pokemon.clearVolatile(); pokemon.lastMove = ''; this.battle.lastMove = 'switch-in'; - if (['batonpass', 'zbatonpass', 'shedtail'].includes(this.lastPokemon?.lastMove!)) { - pokemon.copyVolatileFrom(this.lastPokemon!, this.lastPokemon!.lastMove! === 'shedtail' ? 'shedtail' : false); + const effect = Dex.getEffect(kwArgs.from); + if (['batonpass', 'zbatonpass', 'shedtail'].includes(effect.id)) { + pokemon.copyVolatileFrom(this.lastPokemon!, effect.id === 'shedtail' ? 'shedtail' : false); } this.battle.scene.animSummon(pokemon, slot); @@ -877,13 +878,13 @@ export class Side { this.battle.scene.animSummon(pokemon, slot, true); } switchOut(pokemon: Pokemon, kwArgs: KWArgs, slot = pokemon.slot) { - if (!['batonpass', 'zbatonpass', 'shedtail'].includes(pokemon.lastMove)) { + const effect = Dex.getEffect(kwArgs.from); + if (!['batonpass', 'zbatonpass', 'shedtail'].includes(effect.id)) { pokemon.clearVolatile(); } else { pokemon.removeVolatile('transform' as ID); pokemon.removeVolatile('formechange' as ID); } - const effect = Dex.getEffect(kwArgs.from); if (!['batonpass', 'zbatonpass', 'shedtail', 'teleport'].includes(effect.id)) { this.battle.log(['switchout', pokemon.ident], {from: effect.id}); } @@ -894,7 +895,7 @@ export class Side { this.battle.scene.animUnsummon(pokemon); } - swapTo(pokemon: Pokemon, slot: number, kwArgs: KWArgs) { + swapTo(pokemon: Pokemon, slot: number) { if (pokemon.slot === slot) return; let target = this.active[slot]; @@ -3492,7 +3493,7 @@ export class Battle { if (poke.side.active[slot]) { poke.side.switchOut(poke.side.active[slot]!, kwArgs); } - poke.side.switchIn(poke); + poke.side.switchIn(poke, kwArgs); } else if (args[0] === 'replace') { poke.side.replace(poke); } else { @@ -3519,7 +3520,7 @@ export class Battle { const target = poke.side.active[targetIndex]; if (target) args[2] = target.ident; } - poke.side.swapTo(poke, targetIndex, kwArgs); + poke.side.swapTo(poke, targetIndex); } this.log(args, kwArgs); break; From ead0fd35302615771296fce74598b93d2ed6a20f Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Tue, 22 Nov 2022 14:08:36 -0600 Subject: [PATCH 335/770] Add support for showing hidden rooms in their own room list category (#2022) Requested by US. This PR makes it so there's a button at the bottom of the roomlist you can click to see rooms marked as hidden. Server-side changes to follow. --- js/client-rooms.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/js/client-rooms.js b/js/client-rooms.js index 9ad1af54ff..a2243a0e53 100644 --- a/js/client-rooms.js +++ b/js/client-rooms.js @@ -16,6 +16,7 @@ var buf = '
        '; buf += '

        Rooms filter:

        '; buf += '

        Loading...

        '; + buf += '

        '; buf += '

        '; this.$el.html(buf); app.on('response:rooms', this.update, this); @@ -71,6 +72,13 @@ app.tryJoinRoom(room); }); }, + toggleMoreRooms: function () { + this.showMoreRooms = !this.showMoreRooms; + this.updateRoomList(); + this.$el.find('button[name=toggleMoreRooms]').text( + this.showMoreRooms ? 'Hide more rooms' : 'Show more rooms' + ); + }, update: function (rooms) { if (rooms) { this.lastUpdate = new Date().getTime(); @@ -142,6 +150,7 @@ var spotlightRooms = []; var officialRooms = []; var otherRooms = []; + var hiddenRooms = []; for (var i = 0; i < allRooms.length; i++) { var roomData = allRooms[i]; if (roomData.spotlight) { @@ -149,6 +158,8 @@ spotlightLabel = roomData.spotlight; } else if (roomData.section === 'Official') { officialRooms.push(roomData); + } else if (roomData.privacy === 'hidden') { + hiddenRooms.push(roomData); } else { otherRooms.push(roomData); } @@ -163,8 +174,10 @@ ) ); this.$('.roomlist').last().html( - otherRooms.length ? - '

        Chat rooms

        ' + otherRooms.sort(this.compareRooms).map(this.renderRoomBtn).join("") : '' + (otherRooms.length ? + '

        Chat rooms

        ' + otherRooms.sort(this.compareRooms).map(this.renderRoomBtn).join("") : '') + + (hiddenRooms.length && this.showMoreRooms ? + '

        Hidden rooms

        ' + hiddenRooms.sort(this.compareRooms).map(this.renderRoomBtn).join("") : '') ); }, roomlist: function () { From f97d6fab261a1a0a7a8d91c8c0741509be6fe439 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 23 Nov 2022 13:46:48 -0500 Subject: [PATCH 336/770] Use proper fail message for Shed Tail (#2024) --- src/battle-animations-moves.ts | 2 ++ src/battle-text-parser.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/battle-animations-moves.ts b/src/battle-animations-moves.ts index 870d203d09..95ae4f751d 100644 --- a/src/battle-animations-moves.ts +++ b/src/battle-animations-moves.ts @@ -32467,3 +32467,5 @@ BattleMoveAnims['shellsidearmphysical'] = {anim: BattleMoveAnims['poisonjab'].an BattleMoveAnims['shellsidearmspecial'] = {anim: BattleMoveAnims['sludgebomb'].anim}; BattleMoveAnims['surgingstrikes'] = {anim: BattleMoveAnims['aquajet'].anim}; BattleMoveAnims['eeriespell'] = {anim: BattleMoveAnims['psyshock'].anim}; + +BattleMoveAnims['shedtail'] = {anim: BattleMoveAnims['substitute'].anim}; diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 672f8c10e2..647be428ed 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -1042,7 +1042,7 @@ class BattleTextParser { } templateId = 'fail'; - if (['brn', 'frz', 'par', 'psn', 'slp', 'substitute'].includes(id)) { + if (['brn', 'frz', 'par', 'psn', 'slp', 'substitute', 'shedtail'].includes(id)) { templateId = 'alreadyStarted'; } if (kwArgs.heavy) templateId = 'failTooHeavy'; From 2fadc5462cd2f6cdfaadf744d0ab9c9bf02a3d83 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 23 Nov 2022 13:47:23 -0500 Subject: [PATCH 337/770] Tooltips: Add gen 9 changes (#2025) --- src/battle-dex-data.ts | 4 ++ src/battle-tooltips.ts | 117 +++++++++++++++++++++++++++++++---------- src/battle.ts | 59 +++++++++++---------- 3 files changed, 124 insertions(+), 56 deletions(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index 2a81f3a381..bab4849613 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -1120,10 +1120,14 @@ interface MoveFlags { recharge?: 1 | 0; /** Bounced back to the original user by Magic Coat or the Magic Bounce Ability. */ reflectable?: 1 | 0; + /** Power is multiplied by 1.5 when used by a Pokemon with the Sharpness Ability. */ + slicing?: 1 | 0; /** Can be stolen from the original user and instead used by another Pokemon using Snatch. */ snatch?: 1 | 0; /** Has no effect on Pokemon with the Soundproof Ability. */ sound?: 1 | 0; + /** Activates the effects of the Wind Power and Wind Rider Abilities. */ + wind?: 1 | 0; } type MoveTarget = 'normal' | 'any' | 'adjacentAlly' | 'adjacentFoe' | 'adjacentAllyOrSelf' | // single-target diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 776efda76e..094a52bb6a 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -743,6 +743,12 @@ class BattleTooltips { if (move.flags.bullet) { text += `

        ✓ Bullet-like (doesn't affect Bulletproof pokemon)

        `; } + if (move.flags.slicing) { + text += `

        ✓ Slicing (boosted by Sharpness)

        `; + } + if (move.flags.wind) { + text += `

        ✓ Wind (activates Wind Power and Wind Rider)

        `; + } } return text; } @@ -1060,16 +1066,8 @@ class BattleTooltips { } let weather = this.battle.weather; - if (weather) { - // Check if anyone has an anti-weather ability - outer: for (const side of this.battle.sides) { - for (const active of side.active) { - if (active && ['Air Lock', 'Cloud Nine'].includes(active.ability)) { - weather = '' as ID; - break outer; - } - } - } + if (this.battle.abilityActive(['Air Lock', 'Cloud Nine'])) { + weather = '' as ID; } if (item === 'choiceband' && !clientPokemon?.volatiles['dynamax']) { @@ -1085,6 +1083,9 @@ class BattleTooltips { if (this.battle.gen >= 4 && this.pokemonHasType(pokemon, 'Rock') && weather === 'sandstorm') { stats.spd = Math.floor(stats.spd * 1.5); } + if (this.pokemonHasType(pokemon, 'Ice') && weather === 'snow') { + stats.def = Math.floor(stats.def * 1.5); + } if (ability === 'sandrush' && weather === 'sandstorm') { speedModifiers.push(2); } @@ -1093,9 +1094,15 @@ class BattleTooltips { } if (item !== 'utilityumbrella') { if (weather === 'sunnyday' || weather === 'desolateland') { + if (ability === 'chlorophyll') { + speedModifiers.push(2); + } if (ability === 'solarpower') { stats.spa = Math.floor(stats.spa * 1.5); } + if (ability === 'orichalcumpulse') { + stats.atk = Math.floor(stats.atk * 1.3); + } let allyActive = clientPokemon?.side.active; if (allyActive) { for (const ally of allyActive) { @@ -1108,11 +1115,10 @@ class BattleTooltips { } } } - if (ability === 'chlorophyll' && (weather === 'sunnyday' || weather === 'desolateland')) { - speedModifiers.push(2); - } - if (ability === 'swiftswim' && (weather === 'raindance' || weather === 'primordialsea')) { - speedModifiers.push(2); + if (weather === 'raindance' || weather === 'primordialsea') { + if (ability === 'swiftswim') { + speedModifiers.push(2); + } } } } @@ -1121,13 +1127,22 @@ class BattleTooltips { stats.spa = Math.floor(stats.spa * 0.5); } if (clientPokemon) { - if ('slowstart' in clientPokemon.volatiles) { + if (clientPokemon.volatiles['slowstart']) { stats.atk = Math.floor(stats.atk * 0.5); speedModifiers.push(0.5); } - if (ability === 'unburden' && 'itemremoved' in clientPokemon.volatiles && !item) { + if (ability === 'unburden' && clientPokemon.volatiles['itemremoved'] && !item) { speedModifiers.push(2); } + for (const statName of Dex.statNamesExceptHP) { + if (clientPokemon.volatiles['protosynthesis' + statName] || clientPokemon.volatiles['quarkdrive' + statName]) { + if (statName === 'spe') { + speedModifiers.push(1.5); + } else { + stats[statName] = Math.floor(stats[statName] * 1.3); + } + } + } } if (ability === 'marvelscale' && pokemon.status) { stats.def = Math.floor(stats.def * 1.5); @@ -1144,8 +1159,13 @@ class BattleTooltips { if (ability === 'grasspelt' && this.battle.hasPseudoWeather('Grassy Terrain')) { stats.def = Math.floor(stats.def * 1.5); } - if (ability === 'surgesurfer' && this.battle.hasPseudoWeather('Electric Terrain')) { - speedModifiers.push(2); + if (this.battle.hasPseudoWeather('Electric Terrain')) { + if (ability === 'surgesurfer') { + speedModifiers.push(2); + } + if (ability === 'hadronengine') { + stats.spa = Math.floor(stats.spa * 1.3); + } } if (item === 'choicespecs' && !clientPokemon?.volatiles['dynamax']) { stats.spa = Math.floor(stats.spa * 1.5); @@ -1186,6 +1206,18 @@ class BattleTooltips { if (ability === 'furcoat') { stats.def *= 2; } + if (this.battle.abilityActive('Vessel of Ruin', clientPokemon)) { + stats.spa = Math.floor(stats.spa * 0.75); + } + if (this.battle.abilityActive('Sword of Ruin', clientPokemon)) { + stats.def = Math.floor(stats.def * 0.75); + } + if (this.battle.abilityActive('Tablets of Ruin', clientPokemon)) { + stats.atk = Math.floor(stats.atk * 0.75); + } + if (this.battle.abilityActive('Beads of Ruin', clientPokemon)) { + stats.spd = Math.floor(stats.spd * 0.75); + } const sideConditions = this.battle.mySide.sideConditions; if (sideConditions['tailwind']) { speedModifiers.push(2); @@ -1395,15 +1427,32 @@ class BattleTooltips { moveType = 'Psychic'; } } + if (move.id === 'terablast' && pokemon.teraType) { + moveType = pokemon.teraType as TypeName; + } // Aura Wheel as Morpeko-Hangry changes the type to Dark if (move.id === 'aurawheel' && pokemon.getSpeciesForme() === 'Morpeko-Hangry') { moveType = 'Dark'; } + // Raging Bull's type depends on the Tauros forme + if (move.id === 'ragingbull') { + switch (pokemon.getSpeciesForme()) { + case 'Tauros-Paldea': + moveType = 'Fighting'; + break; + case 'Tauros-Paldea-Fire': + moveType = 'Fire'; + break; + case 'Tauros-Paldea-Water': + moveType = 'Water'; + break; + } + } // Other abilities that change the move type. const noTypeOverride = [ - 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'struggle', 'technoblast', 'terrainpulse', 'weatherball', + 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'struggle', 'technoblast', 'terablast', 'terrainpulse', 'weatherball', ]; if (!noTypeOverride.includes(move.id)) { if (this.battle.rules['Revelationmons Mod']) { @@ -1451,7 +1500,7 @@ class BattleTooltips { value.set(0, "Poison type"); return value; } - if (move.id === 'blizzard') { + if (move.id === 'blizzard' && this.battle.gen >= 4) { value.weatherModify(0, 'Hail'); value.weatherModify(0, 'Snow'); } @@ -1604,8 +1653,11 @@ class BattleTooltips { else basePower = 20; value.set(basePower); } - if (move.id === 'hex' && target?.status) { - value.modify(2, 'Hex + status'); + if (['hex', 'infernalparade'].includes(move.id) && target?.status) { + value.modify(2, move.name + ' + status'); + } + if (move.id === 'lastrespects') { + value.set(Math.min(50 + 50 * pokemon.side.pokemon.filter(p => p.fainted).length)); } if (move.id === 'punishment' && target) { let boostCount = 0; @@ -1638,9 +1690,9 @@ class BattleTooltips { if (move.id === 'magnitude') { value.setRange(10, 150); } - if (move.id === 'venoshock' && target) { + if (['venoshock', 'barbbarrage'].includes(move.id) && target) { if (['psn', 'tox'].includes(target.status)) { - value.modify(2, 'Venoshock + Poison'); + value.modify(2, move.name + ' + Poison'); } } if (move.id === 'wakeupslap' && target) { @@ -1744,6 +1796,9 @@ class BattleTooltips { if (pokemon.status === 'brn' && move.category === 'Special') { value.abilityModify(1.5, "Flare Boost"); } + if (move.flags['punch']) { + value.abilityModify(1.2, 'Iron Fist'); + } if (move.flags['pulse']) { value.abilityModify(1.5, "Mega Launcher"); } @@ -1774,6 +1829,9 @@ class BattleTooltips { if (move.flags['sound']) { value.abilityModify(1.3, "Punk Rock"); } + if (move.flags['slicing']) { + value.abilityModify(1.5, "Sharpness"); + } if (target) { if (["MF", "FM"].includes(pokemon.gender + target.gender)) { value.abilityModify(0.75, "Rivalry"); @@ -1782,7 +1840,7 @@ class BattleTooltips { } } const noTypeOverride = [ - 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'struggle', 'technoblast', 'terrainpulse', 'weatherball', + 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'struggle', 'technoblast', 'terablast', 'terrainpulse', 'weatherball', ]; if ( move.category !== 'Status' && !noTypeOverride.includes(move.id) && !move.isZ && !move.isMax && @@ -1798,9 +1856,6 @@ class BattleTooltips { value.abilityModify(1.2, "Normalize"); } } - if (move.flags['punch']) { - value.abilityModify(1.2, 'Iron Fist'); - } if (move.recoil || move.hasCrashDamage) { value.abilityModify(1.2, 'Reckless'); } @@ -1987,6 +2042,10 @@ class BattleTooltips { return value; } + if (itemName === 'Punching Glove' && move.flags['punch']) { + value.itemModify(1.1); + } + return value; } getPokemonTypes(pokemon: Pokemon | ServerPokemon): ReadonlyArray { diff --git a/src/battle.ts b/src/battle.ts index 47404217bf..a94f6b0441 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1165,26 +1165,37 @@ export class Battle { } return false; } - ngasActive() { - for (const side of this.sides) { + getAllActive() { + const pokemonList = []; + // Sides 3 and 4 are synced with sides 1 and 2, so they don't need to be checked + for (let i = 0; i < 2; i++) { + const side = this.sides[i]; for (const active of side.active) { - if (active && !active.fainted && active.ability === 'Neutralizing Gas' && !active.volatiles['gastroacid']) { - return true; + if (active && !active.fainted) { + pokemonList.push(active); } } } + return pokemonList; + } + ngasActive() { + for (const active of this.getAllActive()) { + if (active.ability === 'Neutralizing Gas' && !active.volatiles['gastroacid']) { + return true; + } + } return false; } - abilityActive(abilities: string[]) { + abilityActive(abilities: string | string[], excludePokemon?: Pokemon | null) { + if (typeof abilities === 'string') abilities = [abilities]; if (this.ngasActive()) { abilities = abilities.filter(a => this.dex.abilities.get(a).isPermanent); if (!abilities.length) return false; } - for (const side of this.sides) { - for (const active of side.active) { - if (active && !active.fainted && abilities.includes(active.ability) && !active.volatiles['gastroacid']) { - return true; - } + for (const active of this.getAllActive()) { + if (active === excludePokemon) continue; + if (abilities.includes(active.ability) && !active.volatiles['gastroacid']) { + return true; } } return false; @@ -1443,7 +1454,7 @@ export class Battle { } } let pp = 1; - if (this.abilityActive(['Pressure']) && move.id !== 'stickyweb') { + if (this.abilityActive('Pressure') && move.id !== 'stickyweb') { const foeTargets = []; const moveTarget = move.pressureTarget; @@ -1454,10 +1465,10 @@ export class Battle { // Hardcode for moves without a target in singles foeTargets.push(pokemon.side.foe.active[0]); } else if (['all', 'allAdjacent', 'allAdjacentFoes', 'foeSide'].includes(moveTarget)) { - // We loop through all sides here for FFA - for (const side of this.sides) { - if (side === pokemon.side || side === pokemon.side.ally) continue; - for (const active of side.active) { + for (const active of this.getAllActive()) { + if (active === pokemon) continue; + // Pressure affects allies in gen 3 and 4 + if (this.gen <= 4 || (active.side !== pokemon.side && active.side.ally !== pokemon.side)) { foeTargets.push(active); } } @@ -1890,14 +1901,10 @@ export class Battle { } case '-clearallboost': { let timeOffset = this.scene.timeOffset; - for (const side of this.sides) { - for (const active of side.active) { - if (active) { - active.boosts = {}; - this.scene.timeOffset = timeOffset; - this.scene.resultAnim(active, 'Stats reset', 'neutral'); - } - } + for (const active of this.getAllActive()) { + active.boosts = {}; + this.scene.timeOffset = timeOffset; + this.scene.resultAnim(active, 'Stats reset', 'neutral'); } this.log(args, kwArgs); @@ -2978,10 +2985,8 @@ export class Battle { switch (effect.id) { case 'gravity': if (this.seeking !== null) break; - for (const side of this.sides) { - for (const active of side.active) { - if (active) this.scene.runOtherAnim('gravity' as ID, [active]); - } + for (const active of this.getAllActive()) { + this.scene.runOtherAnim('gravity' as ID, [active]); } break; } From 6ee442f0452cfb85727b7a48668c6f7d35fc678e Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Fri, 25 Nov 2022 18:48:15 -0700 Subject: [PATCH 338/770] Tooltips: Show Eviolite boost on Hisuian prevos (#2026) --- src/battle-tooltips.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 094a52bb6a..7cf9071cc7 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1150,7 +1150,9 @@ class BattleTooltips { const isNFE = Dex.species.get(serverPokemon.speciesForme).evos?.some(evo => { const evoSpecies = Dex.species.get(evo); return !evoSpecies.isNonstandard || - evoSpecies.isNonstandard === Dex.species.get(serverPokemon.speciesForme)?.isNonstandard; + evoSpecies.isNonstandard === Dex.species.get(serverPokemon.speciesForme)?.isNonstandard || + // Pokemon with Hisui evolutions + evoSpecies.isNonstandard === "Unobtainable"; }); if (item === 'eviolite' && isNFE) { stats.def = Math.floor(stats.def * 1.5); From b22340dd468b5dd4b8803818677902ba5ec8a6eb Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Fri, 25 Nov 2022 20:48:46 -0500 Subject: [PATCH 339/770] Fix Happiness/HP type not being editable in Gen 9 natdex (#2028) --- js/client-teambuilder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 9d7fc5e998..5f207bb502 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -2598,7 +2598,7 @@ var set = this.curSet; var isLetsGo = this.curTeam.format.includes('letsgo'); var isBDSP = this.curTeam.format.includes('bdsp'); - var isNatDex = this.curTeam.gen === 8 && this.curTeam.format.includes('nationaldex'); + var isNatDex = this.curTeam.format.includes('nationaldex'); var species = this.curTeam.dex.species.get(set.species); if (!set) return; buf += '

        Details

        '; From c2365f3b164d598e62aa98f2d86af4760573c82b Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Fri, 25 Nov 2022 19:50:04 -0600 Subject: [PATCH 340/770] Support multiple generations of Metronome Battle (#2029) --- build-tools/build-indexes | 16 ++++++++-------- js/client-teambuilder.js | 2 +- src/battle-dex-search.ts | 6 +++--- src/battle-tooltips.ts | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index b40ffc33ef..4dd1a24f00 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -321,13 +321,13 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const NFE = GENS.map(num => num + 0.3); const STADIUM = [2.04, 1.04]; const NATDEX = [9.1, 8.1]; - const OTHER = [8.6, 8.4, 8.2, 8.1, -8.4, -8.6, 7.1]; + const OTHER = [9.2, 8.6, 8.4, 8.2, 8.1, -8.4, -8.6, 7.1]; // process.stdout.write("\n "); for (const genIdent of [...GENS, ...DOUBLES, ...VGC, ...NFE, ...STADIUM, ...OTHER, ...NATDEX]) { const isLetsGo = (genIdent === 7.1); const isBDSP = (genIdent === 8.6 || genIdent === -8.6); - const isMetBattle = (genIdent === 8.2); + const isMetBattle = ('' + genIdent).endsWith('.2'); const isNFE = ('' + genIdent).endsWith('.3'); const isDLC1 = (genIdent === 8.4 || genIdent === -8.4); const isNatDex = ('' + genIdent).endsWith('.1') && genIdent > 8; @@ -369,7 +369,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (species.tier === 'CAP LC') tier = 'LC'; if (species.tier === 'CAP NFE') tier = 'NFE'; if (species.tier === 'CAP') tier = 'OU'; - const format = Dex.formats.get('gen8metronomebattle'); + const format = Dex.formats.get(gen + 'metronomebattle'); let bst = 0; for (const stat of Object.values(species.baseStats)) { bst += stat; @@ -473,10 +473,10 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable['gen' + genNum + 'natdex'].monotypeBans = monotypeBans; BattleTeambuilderTable['gen' + genNum + 'natdex'].formatSlices = formatSlices; } else if (isMetBattle) { - BattleTeambuilderTable['metronome'] = {}; - BattleTeambuilderTable['metronome'].tiers = tiers; - BattleTeambuilderTable['metronome'].items = items; - BattleTeambuilderTable['metronome'].formatSlices = formatSlices; + BattleTeambuilderTable[gen + 'metronome'] = {}; + BattleTeambuilderTable[gen + 'metronome'].tiers = tiers; + BattleTeambuilderTable[gen + 'metronome'].items = items; + BattleTeambuilderTable[gen + 'metronome'].formatSlices = formatSlices; } else if (isNFE) { BattleTeambuilderTable[gen + 'nfe'] = {}; BattleTeambuilderTable[gen + 'nfe'].tiers = tiers; @@ -595,7 +595,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } } if (isMetBattle) { - const banlist = Dex.formats.getRuleTable(Dex.formats.get('gen8metronomebattle')); + const banlist = Dex.formats.getRuleTable(Dex.formats.get(gen + 'metronomebattle')); if (banlist.isBanned('item:' + item.id)) continue; } switch (id) { diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 5f207bb502..0289078acb 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -136,7 +136,7 @@ update: function () { teams = Storage.teams; if (this.curTeam) { - this.ignoreEVLimits = (this.curTeam.gen < 3 || (this.curTeam.format.includes('hackmons') && this.curTeam.gen !== 6) || this.curTeam.format === 'gen8metronomebattle'); + this.ignoreEVLimits = (this.curTeam.gen < 3 || (this.curTeam.format.includes('hackmons') && this.curTeam.gen !== 6) || this.curTeam.format.includes('metronomebattle')); if (this.curSet) { return this.updateSetView(); } diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index fbe904b754..c90a60759d 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -905,7 +905,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { } else if (this.formatType === 'natdex') { table = table['gen' + this.dex.gen + 'natdex']; } else if (this.formatType === 'metronome') { - table = table['metronome']; + table = table['gen' + dex.gen + 'metronome']; } else if (this.formatType === 'nfe') { table = table['gen' + dex.gen + 'nfe']; } else if (this.formatType?.startsWith('dlc1')) { @@ -1087,7 +1087,7 @@ class BattleAbilitySearch extends BattleTypedSearch<'ability'> { abilitySet.push(['header', "Special Event Ability"]); abilitySet.push(['ability', toID(species.abilities['S'])]); } - if (isAAA || format === 'metronomebattle' || isHackmons) { + if (isAAA || format.includes('metronomebattle') || isHackmons) { let abilities: ID[] = []; for (let i in this.getTable()) { const ability = dex.abilities.get(i); @@ -1149,7 +1149,7 @@ class BattleItemSearch extends BattleTypedSearch<'item'> { } else if (this.formatType === 'natdex') { table = table['gen' + this.dex.gen + 'natdex']; } else if (this.formatType === 'metronome') { - table = table['metronome']; + table = table['gen' + this.dex.gen + 'metronome']; } else if (this.dex.gen < 9) { table = table['gen' + this.dex.gen]; } diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 7cf9071cc7..0bc72300e5 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -2246,7 +2246,7 @@ class BattleStatGuesser { let needsFourMoves = !['unown', 'ditto'].includes(species.id); let moveids = set.moves.map(toID); if (moveids.includes('lastresort' as ID)) needsFourMoves = false; - if (set.moves.length < 4 && needsFourMoves && this.formatid !== 'gen8metronomebattle') { + if (set.moves.length < 4 && needsFourMoves && !this.formatid.includes('metronomebattle')) { return '?'; } From c6c6eb40440ead006ea221aee1cc0fe994e76639 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Wed, 30 Nov 2022 18:32:25 -0600 Subject: [PATCH 341/770] Support changing namecolors through the loginserver (#2034) * Support changing namecolors through the loginserver * Update lib/dispatcher.lib.php --- js/client.js | 5 ++++ lib/dispatcher.lib.php | 61 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/js/client.js b/js/client.js index b1f76bd38f..399031b749 100644 --- a/js/client.js +++ b/js/client.js @@ -678,6 +678,11 @@ function toId() { Storage.whenAppLoaded.load(this); + // load custom colors from loginserver + $.get('/config/colors.json', {}, function (data) { + Object.assign(Config.customcolors, data); + }); + this.initializeConnection(); }, /** diff --git a/lib/dispatcher.lib.php b/lib/dispatcher.lib.php index 9b5eafc727..809a79b96a 100644 --- a/lib/dispatcher.lib.php +++ b/lib/dispatcher.lib.php @@ -112,7 +112,7 @@ public function findServer() { } return null; } else { - $server =& $PokemonServers[$serverid]; + $server = & $PokemonServers[$serverid]; if (empty($server['skipipcheck']) && empty($server['token']) && $serverid !== 'showdown') { if (!isset($server['ipcache'])) { $server['ipcache'] = gethostbyname($server['server']); @@ -356,6 +356,65 @@ public function updateuserstats($dispatcher, &$reqData, &$out) { $dispatcher->setPrefix(''); // No need for prefix since only usable by server. } + public function updatenamecolor($dispatcher, &$reqData, &$out) { + global $psdb, $psconfig, $users; + $server = $dispatcher->findServer(); + if (!isset($psconfig['mainserver']) || !$server || $server['id'] !== $psconfig['mainserver']) { + $out['actionerror'] = 'Access denied'; + return; + } + if (!isset($reqData['userid']) || !mb_strlen($users->userid($reqData['userid']))) { + $out['actionerror'] = 'No userid was specified.'; + return; + } + $userid = $users->userid($reqData['userid']); + if (!isset($reqData['source'])) { + $out['actionerror'] = 'No color adjustment was specified.'; + return; + } + if (strlen($userid) > 18) { + $out['actionerror'] = 'Usernames can only be 18 characters long'; + return; + } + if (!isset($reqData['by']) || !mb_strlen($users->userid($reqData['by']))) { + $out['actionerror'] = 'Specify the action\'s actor.'; + return; + } + $colors = array(); + $path = realpath(__DIR__ . '/../config/colors.json'); + try { + $data = file_get_contents($path, true); + $colors = json_decode($data, true); + } catch (Exception $e) {} + $modlog_entry = ''; + if (!$reqData['source']) { + if (!isset($colors[$userid])) { + $out['actionerror'] = ( + 'That user does not have a custom color set by the loginserver. ' . + 'Ask an admin to remove it manually if they have one.' + ); + return; + } else { + unset($colors[$userid]); + $modlog_entry = 'Username color was removed'; + } + } else { + $colors[$userid] = $reqData['source']; + $modlog_entry = "Username color was set to \"{$reqData['source']}\""; + } + file_put_contents($path, json_encode($colors)); + + $psdb->query( + "INSERT INTO `{$psdb->prefix}usermodlog`". + "(`userid`, `actorid`, `date`, `ip`, `entry`) " . + "VALUES(?, ?, ?, ?, ?)", + [$userid, $users->userid($reqData['by']), time(), $dispatcher->getIp(), $modlog_entry] + ); + + $out['success'] = true; + return $out; + } + public function prepreplay($dispatcher, &$reqData, &$out) { global $psdb, $users; // include_once dirname(__FILE__) . '/ntbb-ladder.lib.php'; // not clear if this is needed From bb3f7c19b93d3c65cd326080dfc7998fd44d8d18 Mon Sep 17 00:00:00 2001 From: Hisuian Zoroark <96159984+HisuianZoroark@users.noreply.github.com> Date: Thu, 1 Dec 2022 14:02:58 -0500 Subject: [PATCH 342/770] Add support for Revival Blessing (#2023) --- js/client-battle.js | 41 +++++++++++++++++++++++++++++++++++------ src/battle.ts | 12 ++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/js/client-battle.js b/js/client-battle.js index b6be21108e..25a99232e3 100644 --- a/js/client-battle.js +++ b/js/client-battle.js @@ -777,7 +777,17 @@ updateSwitchControls: function (type) { var pos = this.choice.choices.length; - if (type !== 'switchposition' && this.request.forceSwitch !== true && !this.choice.freedomDegrees) { + // Needed so it client does not freak out when only 1 mon left wants to switch out + var atLeast1Reviving = false; + for (var i = 0; i < this.battle.pokemonControlled; i++) { + var pokemon = this.battle.myPokemon[i]; + if (pokemon.reviving) { + atLeast1Reviving = true; + break; + } + } + + if (type !== 'switchposition' && this.request.forceSwitch !== true && (!this.choice.freedomDegrees || atLeast1Reviving)) { while (!this.request.forceSwitch[pos] && pos < 6) { pos = this.choice.choices.push('pass'); } @@ -785,6 +795,7 @@ var switchables = this.request && this.request.side ? this.battle.myPokemon : []; var nearActive = this.battle.nearSide.active; + var isReviving = !!switchables[pos].reviving; var requestTitle = ''; if (type === 'switch2' || type === 'switchposition') { @@ -815,7 +826,9 @@ '' ); } else { - if (this.choice.freedomDegrees >= 1) { + if (isReviving) { + requestTitle += "Choose a fainted Pokémon to revive!"; + } else if (this.choice.freedomDegrees >= 1) { requestTitle += "Choose a Pokémon to send to battle!"; } else { requestTitle += "Switch " + BattleLog.escapeHTML(switchables[pos].name) + " to:"; @@ -825,17 +838,25 @@ for (var i = 0; i < switchables.length; i++) { var pokemon = switchables[i]; var tooltipArgs = 'switchpokemon|' + i; - if (pokemon.fainted || i < this.battle.pokemonControlled || this.choice.switchFlags[i]) { - switchMenu += ' '; } var controls = ( '
        ' + - '
        ' + + '
        ' + '
        ' + switchMenu + '
        ' + '
        ' ); @@ -1221,6 +1242,12 @@ if (!this.choice) return; this.tooltips.hideTooltip(); + if (this.battle.myPokemon[this.choice.choices.length].reviving) { + this.choice.choices.push('switch ' + (parseInt(pos, 10) + 1)); + this.endChoice(); + return; + } + if (pos !== undefined) { // pos === undefined if called by chooseSwitchTarget() this.choice.switchFlags[pos] = true; if (this.choice.freedomDegrees >= 1) { @@ -1292,6 +1319,8 @@ app.addPopupMessage("You are trapped and cannot select " + data[0] + "!"); } else if (data[1] === 'active') { app.addPopupMessage("" + data[0] + " is already in battle!"); + } else if (data[1] === 'notfainted') { + app.addPopupMessage("" + data[0] + " still has energy to battle!"); } else { app.addPopupMessage("" + data[0] + " is already selected!"); } diff --git a/src/battle.ts b/src/battle.ts index a94f6b0441..61a3fe41b8 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1719,6 +1719,18 @@ export class Battle { case 'wish': this.scene.runResidualAnim('wish' as ID, poke); break; + case 'revivalblessing': + this.scene.runResidualAnim('wish' as ID, poke); + const {siden} = this.parsePokemonId(args[1]); + const side = this.sides[siden]; + poke.fainted = false; + poke.status = ''; + this.scene.updateSidebar(side); + // Revived while still on the field + if (!side.active[poke.slot]) { + poke.side.replace(poke); + } + break; } } this.scene.runOtherAnim('heal' as ID, [poke]); From b2f7c0821b8e3d792eb40725a7839a420e16cb7a Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 4 Dec 2022 14:05:32 -0500 Subject: [PATCH 343/770] Teambuilder: Reset Tera Type when changing Pokemon (#2031) --- js/client-teambuilder.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 0289078acb..883adb0b7f 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -3270,6 +3270,7 @@ if (set.shiny) delete set.shiny; if (set.dynamaxLevel) delete set.dynamaxLevel; if (set.gigantamax) delete set.gigantamax; + if (set.teraType) delete set.teraType; if (!this.curTeam.format.includes('hackmons') && species.requiredItems.length === 1) { set.item = species.requiredItems[0]; } else { From 8367fe08fcee7bc6e115c5b5d02a1da17b185709 Mon Sep 17 00:00:00 2001 From: Distrib Date: Sun, 4 Dec 2022 20:06:32 +0100 Subject: [PATCH 344/770] FAQ: Update Groupchat (#2032) Pr for https://www.smogon.com/forums/threads/faq-edit.3710902/ --- website/pages/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/faq.md b/website/pages/faq.md index 44e6d2f420..ee96c2e620 100644 --- a/website/pages/faq.md +++ b/website/pages/faq.md @@ -91,7 +91,7 @@ If you want to join a tournament, click the "join" button or type `/tour join` i ### What are groupchats and how can I make one? -Groupchats on PS! are user-created chatrooms that can be used to talk with friends on any topic allowed by global rules. Tournaments can also be conducted within groupchats. To create your own groupchat, use the command `/makegroupchat [name]`. Unlike typical rooms, the creator of a groupchat attains the rank of Host (★) which grants less privileges than Room Owner (#). +Groupchats on PS! are user-created chatrooms that can be used to talk with friends on any topic allowed by global rules. Tournaments can also be conducted within groupchats. To create your own groupchat, use the command `/makegroupchat [name]`. Unlike typical rooms, the creator of a groupchat attains the rank of Host (★) which grants less privileges than Room Owner (#). Groupchats are only available to trusted users (public room staff / global voice or up). ### How do I change the look / background of PS? From 61830b455347ce2202a37267cddd2e8011164025 Mon Sep 17 00:00:00 2001 From: Distrib Date: Sun, 4 Dec 2022 20:07:06 +0100 Subject: [PATCH 345/770] Add tournament challenge notification sound (#2033) Pr for https://www.smogon.com/forums/threads/highlight-when-you-have-to-play-in-a-tournament.3710289/ --- js/client-chat-tournament.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/client-chat-tournament.js b/js/client-chat-tournament.js index 6d3f73766c..4a61398403 100644 --- a/js/client-chat-tournament.js +++ b/js/client-chat-tournament.js @@ -415,6 +415,7 @@ this.$challengeUserMenu.html(this.renderChallengeUsers()); this.toggleBoxVisibility(true); if (!this.$challenge.hasClass('active')) { + app.playNotificationSound(); if (notify) this.room.notifyOnce("Tournament challenges available", "Room: " + this.room.title, 'tournament-challenges'); } } From 9f42e01b87771656cac5b8ccc45a0c1a3584e638 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Sun, 4 Dec 2022 13:07:37 -0600 Subject: [PATCH 346/770] Tooltips: Make Ruin abilities stack (#2035) --- src/battle-tooltips.ts | 16 ++++------------ src/battle.ts | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 0bc72300e5..d724f9a212 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1208,18 +1208,10 @@ class BattleTooltips { if (ability === 'furcoat') { stats.def *= 2; } - if (this.battle.abilityActive('Vessel of Ruin', clientPokemon)) { - stats.spa = Math.floor(stats.spa * 0.75); - } - if (this.battle.abilityActive('Sword of Ruin', clientPokemon)) { - stats.def = Math.floor(stats.def * 0.75); - } - if (this.battle.abilityActive('Tablets of Ruin', clientPokemon)) { - stats.atk = Math.floor(stats.atk * 0.75); - } - if (this.battle.abilityActive('Beads of Ruin', clientPokemon)) { - stats.spd = Math.floor(stats.spd * 0.75); - } + stats.spa = Math.floor(stats.spa * Math.pow(0.75, this.battle.abilityActive('Vessel of Ruin', clientPokemon))); + stats.def = Math.floor(stats.def * Math.pow(0.75, this.battle.abilityActive('Sword of Ruin', clientPokemon))); + stats.atk = Math.floor(stats.atk * Math.pow(0.75, this.battle.abilityActive('Tablets of Ruin', clientPokemon))); + stats.spd = Math.floor(stats.spd * Math.pow(0.75, this.battle.abilityActive('Beads of Ruin', clientPokemon))); const sideConditions = this.battle.mySide.sideConditions; if (sideConditions['tailwind']) { speedModifiers.push(2); diff --git a/src/battle.ts b/src/battle.ts index 61a3fe41b8..9eb90ae77a 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1186,19 +1186,28 @@ export class Battle { } return false; } + /** + * Returns 1 if the abilities are active and 0 if none are active. If `excludePokemon` was provided, instead + * returns the number of active sources of the abilities. + * @param abilities A string or array of strings containing the name or names of abilities to look for. + * @param excludePokemon A Pokemon to be ignored if the ability/abilities do not affect their source, + * i.e. Sword of Ruin. + */ abilityActive(abilities: string | string[], excludePokemon?: Pokemon | null) { + let activeAbilityCount = 0; if (typeof abilities === 'string') abilities = [abilities]; if (this.ngasActive()) { abilities = abilities.filter(a => this.dex.abilities.get(a).isPermanent); - if (!abilities.length) return false; + if (!abilities.length) return 0; } for (const active of this.getAllActive()) { if (active === excludePokemon) continue; if (abilities.includes(active.ability) && !active.volatiles['gastroacid']) { - return true; + if (!excludePokemon) return 1; + activeAbilityCount++; } } - return false; + return activeAbilityCount; } reset() { this.paused = true; From d7ff75c0666fcc0d80dfa2d321ab7740d27db76a Mon Sep 17 00:00:00 2001 From: Adam Tran Date: Sun, 4 Dec 2022 14:09:06 -0500 Subject: [PATCH 347/770] Tooltip: Count Rage Fist power (#2036) --- src/battle-tooltips.ts | 7 +++++++ src/battle.ts | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index d724f9a212..fe658de5f3 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1784,6 +1784,13 @@ class BattleTooltips { value.setRange(isGKLK ? 20 : 40, 120); } } + // Base power based on times hit + if (move.id === 'ragefist') { + value.set(Math.min(350, 50 + 50 * pokemon.timesAttacked), + pokemon.timesAttacked > 0 + ? `Hit ${pokemon.timesAttacked} time${pokemon.timesAttacked > 1 ? 's' : ''}` + : undefined); + } if (!value.value) return value; // Other ability boosts diff --git a/src/battle.ts b/src/battle.ts index 9eb90ae77a..7f88009ef6 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -103,6 +103,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { /** [[moveName, ppUsed]] */ moveTrack: [string, number][] = []; statusData = {sleepTurns: 0, toxicTurns: 0}; + timesAttacked = 0; sprite: PokemonSprite; @@ -1682,6 +1683,7 @@ export class Battle { break; } } else { + poke.timesAttacked += 1; let damageinfo = '' + Pokemon.getFormattedRange(range, damage[1] === 100 ? 0 : 1, '\u2013'); if (damage[1] !== 100) { let hover = '' + ((damage[0] < 0) ? '\u2212' : '') + @@ -2416,6 +2418,7 @@ export class Battle { poke.boosts = {...tpoke.boosts}; poke.copyTypesFrom(tpoke); poke.ability = tpoke.ability; + poke.timesAttacked = tpoke.timesAttacked; const targetForme = tpoke.volatiles.formechange; const speciesForme = (targetForme && !targetForme[1].endsWith('-Gmax')) ? targetForme[1] : tpoke.speciesForme; const pokemon = tpoke; From 0a41e7bbf82c8e11900b621394260d73ef3b602c Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sun, 4 Dec 2022 12:09:29 -0700 Subject: [PATCH 348/770] Teambuilder: Fix STABmons moves (#2037) --- src/battle-dex-search.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index c90a60759d..c34017d4e3 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1503,6 +1503,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { } else { if (!(dex.gen < 8 || this.formatType === 'natdex') && move.isZ) continue; if (typeof move.isMax === 'string') continue; + if (move.isMax && dex.gen > 8) continue; if (move.isNonstandard === 'Past' && this.formatType !== 'natdex') continue; if (move.isNonstandard === 'LGPE' && this.formatType !== 'letsgo') continue; moves.push(move.id); @@ -1515,7 +1516,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { const move = dex.moves.get(id); if (moves.includes(move.id)) continue; if (move.gen > dex.gen) continue; - if (move.isZ || move.isMax || move.isNonstandard) continue; + if (move.isZ || move.isMax || (move.isNonstandard && move.isNonstandard !== 'Unobtainable')) continue; const speciesTypes: string[] = []; const moveTypes: string[] = []; From dc272cf195c3a04ecb12c79347c8424de172468c Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 4 Dec 2022 14:10:11 -0500 Subject: [PATCH 349/770] Allow Costar to copy crit volatiles (#2038) --- src/battle.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index 7f88009ef6..0fc652a183 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1878,13 +1878,12 @@ export class Battle { case '-copyboost': { let poke = this.getPokemon(args[1])!; let frompoke = this.getPokemon(args[2])!; - let effect = Dex.getEffect(kwArgs.from); let stats = args[3] ? args[3].split(', ') : ['atk', 'def', 'spa', 'spd', 'spe', 'accuracy', 'evasion']; for (const stat of stats) { poke.boosts[stat] = frompoke.boosts[stat]; if (!poke.boosts[stat]) delete poke.boosts[stat]; } - if (this.gen >= 6 && effect.id === 'psychup') { + if (this.gen >= 6) { const volatilesToCopy = ['focusenergy', 'gmaxchistrike', 'laserfocus']; for (const volatile of volatilesToCopy) { if (frompoke.volatiles[volatile]) { From fbc99f55fee6486c3edf8a02b037aae94eb80efe Mon Sep 17 00:00:00 2001 From: Hisuian Zoroark <96159984+HisuianZoroark@users.noreply.github.com> Date: Sun, 4 Dec 2022 14:10:36 -0500 Subject: [PATCH 350/770] Teambuilder: Use doubles tiers for Partners in Crime (#2039) --- src/battle-dex-search.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index c34017d4e3..b9f05f3ad4 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -607,6 +607,7 @@ abstract class BattleTypedSearch { this.dex = Dex.mod('gen8bdsp' as ID); } if (format.includes('doubles') && this.dex.gen > 4 && !this.formatType) this.formatType = 'doubles'; + if (format === 'partnersincrime') this.formatType = 'doubles'; if (format.startsWith('ffa') || format === 'freeforall') this.formatType = 'doubles'; if (format.includes('letsgo')) { this.formatType = 'letsgo'; @@ -891,7 +892,8 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { this.formatType !== 'letsgo' && this.formatType !== 'bdspdoubles' && this.formatType !== 'dlc1doubles' && ( format.includes('doubles') || format.includes('triples') || - format === 'freeforall' || format.startsWith('ffa') + format === 'freeforall' || format.startsWith('ffa') || + format === 'partnersincrime' ) ) { table = table['gen' + dex.gen + 'doubles']; From bd4c81dc67563e1819ebe96599a05729fc08cbbf Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 4 Dec 2022 14:26:14 -0500 Subject: [PATCH 351/770] Fix Eviolite NFE check for past gens (#2040) --- build-tools/build-indexes | 11 +++++------ src/battle-tooltips.ts | 6 +++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 4dd1a24f00..e8518a9ac5 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -928,7 +928,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } // Client relevant data that should be overriden by past gens and mods - const overrideSpeciesKeys = ['abilities', 'baseStats', 'cosmeticFormes', 'requiredItems', 'types', 'unreleasedHidden']; + const overrideSpeciesKeys = ['abilities', 'baseStats', 'cosmeticFormes', 'isNonstandard', 'requiredItems', 'types', 'unreleasedHidden']; const overrideMoveKeys = ['accuracy', 'basePower', 'category', 'desc', 'flags', 'isNonstandard', 'noSketch', 'pp', 'priority', 'shortDesc', 'target', 'type']; const overrideAbilityKeys = ['desc', 'isNonstandard', 'rating', 'shortDesc']; @@ -947,8 +947,8 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const overrideSpeciesData = {}; BattleTeambuilderTable[gen].overrideSpeciesData = overrideSpeciesData; for (const id in genData.Pokedex) { - const curEntry = genData.Pokedex[id]; - const nextEntry = nextGenData.Pokedex[id]; + const curEntry = genDex.species.get(id); + const nextEntry = nextGenDex.species.get(id); for (const key of overrideSpeciesKeys) { if (JSON.stringify(curEntry[key]) !== JSON.stringify(nextEntry[key])) { if (!overrideSpeciesData[id]) overrideSpeciesData[id] = {}; @@ -1019,13 +1019,12 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const modDex = Dex.mod(mod); const modData = modDex.data; const parentDex = Dex.forGen(modDex.gen); - const parentData = parentDex.data; const overrideSpeciesData = {}; BattleTeambuilderTable[mod].overrideSpeciesData = overrideSpeciesData; for (const id in modData.Pokedex) { - const modEntry = modData.Pokedex[id]; - const parentEntry = parentData.Pokedex[id]; + const modEntry = modDex.species.get(id); + const parentEntry = parentDex.species.get(id); for (const key of overrideSpeciesKeys) { if (JSON.stringify(modEntry[key]) !== JSON.stringify(parentEntry[key])) { if (!overrideSpeciesData[id]) overrideSpeciesData[id] = {}; diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index fe658de5f3..ba20f731c4 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1147,10 +1147,10 @@ class BattleTooltips { if (ability === 'marvelscale' && pokemon.status) { stats.def = Math.floor(stats.def * 1.5); } - const isNFE = Dex.species.get(serverPokemon.speciesForme).evos?.some(evo => { - const evoSpecies = Dex.species.get(evo); + const isNFE = this.battle.dex.species.get(serverPokemon.speciesForme).evos?.some(evo => { + const evoSpecies = this.battle.dex.species.get(evo); return !evoSpecies.isNonstandard || - evoSpecies.isNonstandard === Dex.species.get(serverPokemon.speciesForme)?.isNonstandard || + evoSpecies.isNonstandard === this.battle.dex.species.get(serverPokemon.speciesForme)?.isNonstandard || // Pokemon with Hisui evolutions evoSpecies.isNonstandard === "Unobtainable"; }); From 29ba7f3d2b6f490536e513b8c2c6deba4b554baa Mon Sep 17 00:00:00 2001 From: Distrib Date: Sun, 4 Dec 2022 20:32:47 +0100 Subject: [PATCH 352/770] Add option to confirm before leaving a room (#2027) --- js/client-battle.js | 8 ++++++++ js/client-chat.js | 3 +++ js/client-topbar.js | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/js/client-battle.js b/js/client-battle.js index 25a99232e3..41e9cffc69 100644 --- a/js/client-battle.js +++ b/js/client-battle.js @@ -1470,6 +1470,8 @@ buf += 'Forfeiting makes you lose the battle.'; } else if (this.gameType === 'help') { buf += 'Leaving the room will close the ticket.'; + } else if (this.gameType === 'room') { + buf += 'Are you sure you want to exit this room?'; } else { // game buf += 'Forfeiting makes you lose the game.'; @@ -1477,6 +1479,8 @@ if (this.gameType === 'help') { buf += ' Are you sure?

        '; buf += '

        '; + } else if (this.gameType === 'room') { + buf += '

        '; } else { buf += ' Are you sure?

        '; buf += '

        '; @@ -1505,6 +1509,10 @@ app.removeRoom(this.room.id); } this.close(); + }, + leaveRoom: function (data) { + this.room.send('/noreply /leave'); + this.close(); } }); diff --git a/js/client-chat.js b/js/client-chat.js index 54dabc930d..2d3f78045e 100644 --- a/js/client-chat.js +++ b/js/client-chat.js @@ -1314,6 +1314,9 @@ if (app.rooms[''].games && app.rooms[''].games[this.id]) { app.addPopup(ForfeitPopup, {room: this, sourceEl: e && e.currentTarget, gameType: (this.id.substring(0, 5) === 'help-' ? 'help' : 'game')}); return false; + } else if (Dex.prefs('leavePopupRoom')) { + app.addPopup(ForfeitPopup, {room: this, sourceEl: e && e.currentTarget, gameType: 'room'}); + return false; } return true; }, diff --git a/js/client-topbar.js b/js/client-topbar.js index 4938ae3abe..c7ab31e16e 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -459,6 +459,7 @@ 'change input[name=blockchallenges]': 'setBlockchallenges', 'change input[name=blockpms]': 'setBlockpms', 'change input[name=inchatpm]': 'setInchatpm', + 'change input[name=leavePopupRoom]': 'setLeavePopupRoom', 'change input[name=temporarynotifications]': 'setTemporaryNotifications', 'change input[name=refreshprompt]': 'setRefreshprompt', 'change select[name=bg]': 'setBg', @@ -520,6 +521,7 @@ if (window.Notification) { buf += '

        '; } + buf += '

        '; buf += '

        '; var curLang = toID(Dex.prefs('serversettings').language) || 'english'; var possibleLanguages = { @@ -637,6 +639,10 @@ var refreshprompt = !!e.currentTarget.checked; Storage.prefs('refreshprompt', refreshprompt); }, + setLeavePopupRoom: function (e) { + var leavePopupRoom = !!e.currentTarget.checked; + Storage.prefs('leavePopupRoom', leavePopupRoom); + }, background: function (e) { app.addPopup(CustomBackgroundPopup); }, From de8e7ea0d17305046c957574e52c613eeed50630 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Sat, 10 Dec 2022 17:00:29 -0600 Subject: [PATCH 353/770] Tooltips: Update Supreme Overlord & Last Respects (#2041) --- src/battle-animations.ts | 5 +++++ src/battle-tooltips.ts | 7 ++++++- src/battle.ts | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 11b3bb8774..3f39be9aa2 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -1796,6 +1796,11 @@ export class PokemonSprite extends Sprite { quarkdrivespa: ['Quark Drive: SpA', 'good'], quarkdrivespd: ['Quark Drive: SpD', 'good'], quarkdrivespe: ['Quark Drive: Spe', 'good'], + fallen1: ['Fallen: 1', 'good'], + fallen2: ['Fallen: 2', 'good'], + fallen3: ['Fallen: 3', 'good'], + fallen4: ['Fallen: 4', 'good'], + fallen5: ['Fallen: 5', 'good'], noretreat: ['No Retreat', 'bad'], octolock: ['Octolock', 'bad'], tarshot: ['Tar Shot', 'bad'], diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index ba20f731c4..8576c24685 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1651,7 +1651,7 @@ class BattleTooltips { value.modify(2, move.name + ' + status'); } if (move.id === 'lastrespects') { - value.set(Math.min(50 + 50 * pokemon.side.pokemon.filter(p => p.fainted).length)); + value.set(Math.min(50 + 50 * pokemon.side.faintCounter)); } if (move.id === 'punishment' && target) { let boostCount = 0; @@ -1833,6 +1833,11 @@ class BattleTooltips { if (move.flags['slicing']) { value.abilityModify(1.5, "Sharpness"); } + for (let i = 1; i <= 5 && i <= pokemon.side.faintCounter; i++) { + if (pokemon.volatiles[`fallen${i}`]) { + value.abilityModify(1 + 0.1 * i, "Supreme Overlord"); + } + } if (target) { if (["MF", "FM"].includes(pokemon.gender + target.gender)) { value.abilityModify(0.75, "Rivalry"); diff --git a/src/battle.ts b/src/battle.ts index 0fc652a183..19fe2289dc 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -626,6 +626,7 @@ export class Side { /** [effectName, levels, minDuration, maxDuration] */ sideConditions: {[id: string]: [string, number, number, number]} = {}; + faintCounter = 0; constructor(battle: Battle, n: number) { this.battle = battle; @@ -661,6 +662,7 @@ export class Side { reset() { this.clearPokemon(); this.sideConditions = {}; + this.faintCounter = 0; } setAvatar(avatar: string) { this.avatar = avatar; @@ -939,6 +941,7 @@ export class Side { pokemon.fainted = true; pokemon.hp = 0; + if (pokemon.side.faintCounter < 100) pokemon.side.faintCounter++; this.battle.scene.animFaint(pokemon); } From 8234922d6ea454d24f2f682d9ac10ed62cb30429 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 10 Dec 2022 18:01:00 -0500 Subject: [PATCH 354/770] Add formatted Salt Cure volatile tag (#2042) --- src/battle-animations.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 3f39be9aa2..b11dac0a1f 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -1804,6 +1804,7 @@ export class PokemonSprite extends Sprite { noretreat: ['No Retreat', 'bad'], octolock: ['Octolock', 'bad'], tarshot: ['Tar Shot', 'bad'], + saltcure: ['Salt Cure', 'bad'], doomdesire: null, futuresight: null, mimic: ['Mimic', 'good'], From b20fd7fd7d576d7d1f452fac048020a0e87e6067 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Sat, 10 Dec 2022 17:05:51 -0600 Subject: [PATCH 355/770] Show Tera icon on Terastallized Pokemon's statbars (#2045) --- src/battle-animations.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index b11dac0a1f..4486e6a087 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -2670,6 +2670,9 @@ export class PokemonSprite extends Sprite { if (symbol) { buf += ` ${symbol}`; } + if (pokemon.teraType) { + buf += ` Tera-${pokemon.teraType}`; + } buf += `
        `; buf += `
        `; From f821631a974c1a4d38386684346ea55f173c7a67 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sat, 10 Dec 2022 16:06:45 -0700 Subject: [PATCH 356/770] Add Gen 9 move animations (#2046) --- src/battle-animations-moves.ts | 2688 +++++++++++++++++++++++++++++++- src/battle-animations.ts | 2 +- src/battle-text-parser.ts | 3 +- src/battle.ts | 1 + 4 files changed, 2691 insertions(+), 3 deletions(-) diff --git a/src/battle-animations-moves.ts b/src/battle-animations-moves.ts index 95ae4f751d..d2073f4261 100644 --- a/src/battle-animations-moves.ts +++ b/src/battle-animations-moves.ts @@ -360,6 +360,48 @@ export const BattleMoveAnims: AnimTable = { }, 'accel'); }, }, + victorydance: { + anim(scene, [attacker]) { + scene.backgroundEffect('#987058', 800, 0.3, 400); + BattleOtherAnims.shake.anim(scene, [attacker]); + scene.showEffect('flareball', { + x: attacker.x + 40, + y: attacker.y - 40, + z: attacker.z, + scale: 0.2, + opacity: 1, + time: 0, + }, { + y: attacker.y + 60, + opacity: 0, + time: 400, + }, 'accel'); + scene.showEffect('flareball', { + x: attacker.x - 40, + y: attacker.y - 40, + z: attacker.z, + scale: 0.2, + opacity: 1, + time: 200, + }, { + y: attacker.y + 60, + opacity: 0, + time: 600, + }, 'accel'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y - 40, + z: attacker.z, + scale: 0.2, + opacity: 1, + time: 400, + }, { + y: attacker.y + 60, + opacity: 0, + time: 800, + }, 'accel'); + }, + }, dragondance: { anim(scene, [attacker]) { BattleOtherAnims.shake.anim(scene, [attacker]); @@ -632,9 +674,46 @@ export const BattleMoveAnims: AnimTable = { hail: { anim: BattleOtherAnims.dance.anim, }, - snow: { + snowscape: { anim: BattleOtherAnims.dance.anim, }, + chillyreception: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('#000000', 750, 1, 50); + if (attacker.sp.url) { + const url = attacker.sp.url; + const sprite = { + url: url.replace('-back', ''), + w: attacker.sp.w, + h: attacker.sp.h, + }; + scene.showEffect(sprite, { + x: scene.battle.mySide.x + 65, + y: scene.battle.mySide.y + 65, + z: scene.battle.mySide.z, + scale: 1.5, + opacity: 1, + time: 50, + }, { + opacity: 0, + time: 800, + }, 'decel'); + sprite.url = url; + scene.showEffect(sprite, { + x: scene.battle.mySide.x + 65, + y: scene.battle.mySide.y + 65, + z: scene.battle.mySide.z, + scale: 1.5, + opacity: 0, + time: 800, + }, { + opacity: 1, + time: 1550, + }, 'decel'); + } + scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-hail.png')`, 750, 1, 800); + }, + }, sandstorm: { anim: BattleOtherAnims.dance.anim, }, @@ -850,6 +929,9 @@ export const BattleMoveAnims: AnimTable = { sketch: { anim: BattleOtherAnims.dance.anim, }, + doodle: { + anim: BattleOtherAnims.dance.anim, + }, odorsleuth: { anim: BattleOtherAnims.dance.anim, }, @@ -1448,6 +1530,136 @@ export const BattleMoveAnims: AnimTable = { }, 'decel'); }, }, + orderup: { + anim(scene, [attacker, defender]) { + let xstep = (defender.x - attacker.x) / 5; + let ystep = (defender.y - attacker.y) / 5; + let zstep = (defender.z - attacker.z) / 5; + + const tatsugiriSprite = { + url: `https://${Config.routes.client}/sprites/gen5/tatsugiri${['-droopy', '-stretchy', ''][Math.floor(Math.random() * 3)]}.png`, + w: 96, + h: 96, + }; + + scene.showEffect(tatsugiriSprite, { + x: defender.x, + y: defender.y + 250, + z: defender.z, + scale: 1, + opacity: 1, + time: 0, + }, { + y: defender.y, + scale: 0.5, + time: 300, + }, 'linear'); + scene.showEffect(tatsugiriSprite, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.5, + opacity: 1, + time: 300, + }, { + time: 900, + }, 'linear'); + for (let i = 0; i < 5; i++) { + scene.showEffect('wisp', { + x: attacker.x + xstep * (i + 1), + y: attacker.y + ystep * (i + 1), + z: attacker.z + zstep * (i + 1), + scale: 1, + opacity: 1, + time: 20 * i, + }, { + scale: 2, + opacity: 0, + time: 40 * i + 800, + }, 'linear'); + scene.showEffect('poisonwisp', { + x: attacker.x + xstep * (i + 1), + y: attacker.y + ystep * (i + 1), + z: attacker.z + zstep * (i + 1), + scale: 0.5, + opacity: 0.3, + time: 20 * i, + }, { + scale: 2, + opacity: 0, + time: 40 * i + 800, + }, 'linear'); + } + scene.showEffect('shadowball', { + x: attacker.x, + y: attacker.y, + z: attacker.behind(-15), + scale: 0.5, + opacity: 0.6, + }, { + scale: 0.6, + opacity: 0.2, + time: 700, + }, 'linear', 'fade'); + + scene.showEffect('shadowball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.3, + opacity: 0.1, + time: 300, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1, + time: 500, + }, 'linear', 'explode'); + scene.showEffect('shadowball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.3, + opacity: 0.1, + time: 400, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1, + time: 600, + }, 'linear', 'explode'); + scene.showEffect('shadowball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.3, + opacity: 0.1, + time: 500, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1, + time: 700, + }, 'linear', 'explode'); + scene.showEffect('shadowball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.3, + opacity: 0.1, + time: 600, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1, + time: 800, + }, 'linear', 'explode'); + }, + }, dragonpulse: { anim(scene, [attacker, defender]) { let xstep = (defender.x - attacker.x) / 5; @@ -1873,6 +2085,72 @@ export const BattleMoveAnims: AnimTable = { gyroball: { anim: BattleOtherAnims.spinattack.anim, }, + mortalspin: { + anim(scene, [attacker, defender]) { + scene.showEffect('poisonwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 2, + opacity: 0.5, + time: 0, + }, { + x: defender.x, + y: defender.y + 60, + z: defender.behind(-30), + opacity: 0.8, + time: 400, + }, 'decel', 'explode'); + scene.showEffect('poisonwisp', { + x: defender.x, + y: defender.y + 60, + z: defender.behind(-30), + scale: 2, + opacity: 0.8, + time: 400, + }, { + x: defender.x, + y: defender.y + 5, + z: defender.z, + opacity: 1, + time: 500, + }, 'decel', 'explode'); + BattleOtherAnims.spinattack.anim(scene, [attacker, defender]); + }, + }, + icespinner: { + anim(scene, [attacker, defender]) { + scene.showEffect('iceball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 2, + opacity: 0.5, + time: 0, + }, { + x: defender.x, + y: defender.y + 60, + z: defender.behind(-30), + opacity: 0.8, + time: 400, + }, 'decel', 'explode'); + scene.showEffect('iceball', { + x: defender.x, + y: defender.y + 60, + z: defender.behind(-30), + scale: 2, + opacity: 0.8, + time: 400, + }, { + x: defender.x, + y: defender.y + 5, + z: defender.z, + opacity: 1, + time: 500, + }, 'decel', 'explode'); + BattleOtherAnims.spinattack.anim(scene, [attacker, defender]); + }, + }, voltswitch: { anim(scene, [attacker, defender]) { scene.showEffect('electroball', { @@ -2171,6 +2449,75 @@ export const BattleMoveAnims: AnimTable = { }, 'linear'); }, }, + populationbomb: { + anim(scene, [attacker, defender]) { + BattleOtherAnims.contactattack.anim(scene, [attacker, defender]); + scene.showEffect('fireball', { + x: defender.x + 40, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.6, + }, { + scale: 6, + opacity: 0, + }, 'decel'); + scene.showEffect('leftslash', { + x: defender.x + 40, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.6, + }, { + scale: 6, + opacity: 0, + }, 'decel'); + scene.showEffect('fireball', { + x: defender.x - 40, + y: defender.y - 20, + z: defender.z, + scale: 0, + opacity: 0.6, + time: 150, + }, { + scale: 6, + opacity: 0, + }, 'decel'); + scene.showEffect('rightslash', { + x: defender.x - 40, + y: defender.y - 20, + z: defender.z, + scale: 0, + opacity: 0.6, + time: 150, + }, { + scale: 6, + opacity: 0, + }, 'decel'); + scene.showEffect('fireball', { + x: defender.x + 10, + y: defender.y + 20, + z: defender.z, + scale: 0, + opacity: 0.6, + time: 300, + }, { + scale: 6, + opacity: 0, + }, 'decel'); + scene.showEffect('leftslash', { + x: defender.x + 10, + y: defender.y + 20, + z: defender.z, + scale: 0, + opacity: 0.6, + time: 300, + }, { + scale: 6, + opacity: 0, + }, 'decel'); + }, + }, auroraveil: { anim() {}, }, @@ -4821,6 +5168,9 @@ export const BattleMoveAnims: AnimTable = { falseswipe: { anim: BattleOtherAnims.slashattack.anim, }, + direclaw: { + anim: BattleOtherAnims.clawattack.anim, + }, dragonclaw: { anim: BattleOtherAnims.clawattack.anim, }, @@ -5790,6 +6140,56 @@ export const BattleMoveAnims: AnimTable = { }, 'swing'); }, }, + gigatonhammer: { + anim(scene, [attacker, defender]) { + scene.showEffect('shadowball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.5, + time: 450, + }, { + scale: 2, + opacity: 0, + time: 700, + }, 'linear'); + scene.showEffect('wisp', { + x: defender.x, + y: defender.y - 30, + z: defender.z, + scale: 1, + time: 500, + }, { + x: defender.x + 70, + scale: 0.8, + opacity: 0.3, + time: 800, + }, 'linear', 'fade'); + scene.showEffect('wisp', { + x: defender.x, + y: defender.y - 30, + z: defender.z, + scale: 1, + time: 500, + }, { + x: defender.x - 70, + scale: 0.8, + opacity: 0.3, + time: 800, + }, 'linear', 'fade'); + defender.delay(450); + defender.anim({ + y: defender.y - 30, + z: defender.behind(20), + yscale: 0.5, + time: 200, + }, 'swing'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, heavyslam: { anim(scene, [attacker, defender]) { scene.showEffect('shadowball', { @@ -7989,6 +8389,104 @@ export const BattleMoveAnims: AnimTable = { BattleOtherAnims.drain.anim(scene, [attacker, defender]); }, }, + bitterblade: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('#000000', 800, 0.3, 400); + scene.showEffect('leftslash', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1.5, + opacity: 0.6, + time: 400, + }, { + scale: 2, + opacity: 0, + time: 700, + }, 'accel', 'fade'); + scene.showEffect('bluefireball', { + x: defender.x - 60, + y: defender.y + 70, + z: defender.z, + scale: 0.75, + opacity: 1, + time: 400, + }, { + x: defender.x + 60, + y: defender.y - 70, + scale: 0.6, + opacity: 0, + time: 700, + }, 'decel'); + scene.showEffect('bluefireball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.6, + opacity: 1, + time: 600, + }, { + x: attacker.x, + y: attacker.y, + z: attacker.z, + time: 900, + opacity: 0, + }, 'ballistic2'); + scene.showEffect('bluefireball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.6, + opacity: 1, + time: 650, + }, { + x: attacker.x, + y: attacker.y, + z: attacker.z, + time: 950, + opacity: 0, + }, 'linear'); + scene.showEffect('bluefireball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.6, + opacity: 1, + time: 700, + }, { + x: attacker.x, + y: attacker.y, + z: attacker.z, + time: 1000, + opacity: 0, + }, 'ballistic2Under'); + attacker.anim({ + x: defender.leftof(20), + y: defender.y, + z: defender.behind(-20), + time: 400, + }, 'ballistic2Under'); + attacker.anim({ + x: defender.x, + y: defender.y, + z: defender.z, + time: 50, + }); + attacker.anim({ + time: 500, + }, 'ballistic2'); + defender.delay(425); + defender.anim({ + x: defender.leftof(-20), + y: defender.y, + z: defender.behind(20), + time: 50, + }, 'swing'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, leechlife: { anim(scene, [attacker, defender]) { scene.backgroundEffect('#987058', 800, 0.3, 400); @@ -8423,6 +8921,98 @@ export const BattleMoveAnims: AnimTable = { }, 'accel', 'fade'); }, }, + jetpunch: { + anim(scene, [attacker, defender]) { + scene.showEffect('waterwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.1, + opacity: 1, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1, + time: 200, + }, 'accel', 'fade'); + scene.showEffect('fist', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.1, + opacity: 1, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1, + time: 200, + }, 'accel', 'fade'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.3, + opacity: 1, + time: 200, + }, { + y: defender.y + 50, + opacity: 0, + time: 400, + }, 'accel', 'fade'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.3, + opacity: 1, + time: 200, + }, { + x: defender.x + 50, + opacity: 0, + time: 400, + }, 'accel', 'fade'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.3, + opacity: 1, + time: 200, + }, { + x: defender.x - 50, + opacity: 0, + time: 400, + }, 'accel', 'fade'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.3, + opacity: 1, + time: 200, + }, { + x: defender.x - 25, + y: defender.y - 50, + opacity: 0, + time: 400, + }, 'accel', 'fade'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.3, + opacity: 1, + time: 200, + }, { + x: defender.x + 25, + y: defender.y - 50, + opacity: 0, + time: 400, + }, 'accel', 'fade'); + }, + }, assist: { anim() {}, }, @@ -9166,6 +9756,349 @@ export const BattleMoveAnims: AnimTable = { }, 'swing'); }, }, + armorcannon: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('#124763', 700, 0.6); + scene.backgroundEffect('#FFC001', 300, 0.3, 600); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y + 100, + z: attacker.behind(-20), + scale: 0.5, + xscale: 3, + opacity: 0, + time: 0, + }, { + x: attacker.x, + y: attacker.y, + scale: 0.8, + xscale: 0.8, + opacity: 0.8, + time: 400, + }, 'decel', 'fade'); + scene.showEffect('flareball', { + x: attacker.x - 60, + y: attacker.y - 80, + z: attacker.behind(-20), + scale: 0.5, + yscale: 3, + opacity: 0, + time: 50, + }, { + x: attacker.x, + y: attacker.y, + scale: 1.5, + yscale: 1.5, + opacity: 0.8, + time: 450, + }, 'decel', 'fade'); + + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y, + z: attacker.behind(-20), + scale: 0, + opacity: 0, + time: 0, + }, { + scale: 0.8, + opacity: 0.5, + time: 650, + }, 'decel', 'fade'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y, + z: attacker.behind(-20), + scale: 0, + opacity: 0, + time: 0, + }, { + scale: 1.5, + opacity: 0.8, + time: 650, + }, 'decel', 'fade'); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y, + z: attacker.behind(-20), + scale: 0.3, + opacity: 0.8, + time: 600, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + time: 800, + }, 'accel', 'explode'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y, + z: attacker.behind(-20), + scale: 0.3, + opacity: 0.8, + time: 600, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + time: 800, + }, 'accel', 'explode'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y, + z: attacker.behind(-20), + scale: 0.3, + opacity: 0.8, + time: 600, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + time: 825, + }, 'accel', 'explode'); + + defender.delay(800); + defender.anim({ + z: defender.behind(10), + time: 175, + }, 'swing'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, + torchsong: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('#FFC001', 800, 0.3, 200); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.3, + opacity: 0.8, + time: 0, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + time: 200, + }, 'accel', 'explode'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.3, + opacity: 0.8, + time: 0, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + time: 200, + }, 'accel', 'explode'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.3, + opacity: 0.8, + time: 0, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + time: 225, + }, 'accel', 'explode'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.5, + time: 200, + }, { + z: defender.behind(-50), + scale: 7, + opacity: 0, + time: 600, + }, 'linear'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.5, + time: 350, + }, { + z: defender.behind(-50), + scale: 7, + opacity: 0, + time: 800, + }, 'linear'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.5, + time: 500, + }, { + z: defender.behind(-50), + scale: 7, + opacity: 0, + time: 1000, + }, 'linear'); + }, + }, + chloroblast: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('#36E747', 700, 0.2); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + }, { + x: defender.x + 30, + y: defender.y + 30, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 200, + }, 'linear', 'explode'); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 75, + }, { + x: defender.x + 20, + y: defender.y - 30, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 275, + }, 'linear', 'explode'); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 150, + }, { + x: defender.x - 30, + y: defender.y, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 350, + }, 'linear', 'explode'); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 225, + }, { + x: defender.x - 10, + y: defender.y + 10, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 425, + }, 'linear', 'explode'); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 300, + }, { + x: defender.x + 10, + y: defender.y - 10, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 500, + }, 'linear', 'explode'); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 375, + }, { + x: defender.x - 20, + y: defender.y, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 575, + }, 'linear', 'explode'); + + scene.showEffect('energyball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.5, + time: 550, + }, { + scale: 4, + opacity: 0, + time: 750, + }, 'linear'); + scene.showEffect('energyball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.5, + time: 600, + }, { + scale: 4, + opacity: 0, + time: 800, + }, 'linear'); + + defender.delay(125); + defender.anim({ + z: defender.behind(5), + time: 75, + }, 'swing'); + defender.anim({ + time: 75, + }, 'swing'); + defender.anim({ + z: defender.behind(5), + time: 75, + }, 'swing'); + defender.anim({ + time: 75, + }, 'swing'); + defender.anim({ + z: defender.behind(5), + time: 75, + }, 'swing'); + defender.anim({ + time: 75, + }, 'swing'); + defender.anim({ + z: defender.behind(5), + time: 75, + }, 'swing'); + defender.anim({ + time: 150, + }, 'swing'); + }, + }, hyperbeam: { anim(scene, [attacker, defender]) { scene.backgroundEffect('#000000', 700, 0.2); @@ -9452,6 +10385,127 @@ export const BattleMoveAnims: AnimTable = { }, prepareAnim: BattleOtherAnims.chargestatus.anim, }, + spinout: { + anim(scene, [attacker, defender]) { + for (let i = 0; i < 5; i++) { + scene.showEffect('gear', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 0, + }, { + // Gives a "random" gear break-ish look + x: attacker.x + (50 / i), + y: attacker.y + (i * 5), + scale: 1, + opacity: 0, + time: 300, + }, 'ballistic'); + } + + scene.showEffect('iceball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 0, + }, { + x: attacker.x - 25, + y: attacker.y - 25, + scale: 2, + opacity: 0, + time: 300, + }, 'ballistic'); + scene.showEffect('iceball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 150, + }, { + x: attacker.x + 30, + y: attacker.y - 20, + scale: 2, + opacity: 0, + time: 450, + }, 'ballistic'); + scene.showEffect('iceball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 250, + }, { + x: attacker.x + 5, + y: attacker.y - 40, + scale: 2, + opacity: 0, + time: 550, + }, 'ballistic'); + scene.showEffect('iceball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 300, + }, { + x: attacker.x - 20, + y: attacker.y - 20, + scale: 2, + opacity: 0, + time: 600, + }, 'ballistic'); + + scene.showEffect('iceball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 600, + }, { + scale: 5, + opacity: 0, + time: 900, + }, 'linear'); + scene.showEffect('iceball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 700, + }, { + scale: 8, + opacity: 0, + time: 1000, + }, 'linear'); + attacker.delay(300); + attacker.anim({ + x: defender.x, + y: defender.y, + z: defender.behind(-5), + time: 300, + }, 'accel'); + attacker.anim({ + time: 500, + }, 'ballistic2Back'); + defender.delay(580); + defender.anim({ + z: defender.behind(20), + time: 100, + }, 'swing'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, flamecharge: { anim(scene, [attacker, defender]) { scene.showEffect('fireball', { @@ -10149,6 +11203,109 @@ export const BattleMoveAnims: AnimTable = { }, 'swing'); }, }, + ragingfury: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('linear-gradient(#390000 30%, #B84038)', 600, 0.6, 400); + scene.showEffect('angry', { + x: attacker.x - 10, + y: attacker.y + 50, + z: attacker.z, + scale: 0.5, + opacity: 1, + time: 0, + }, { + scale: 3, + opacity: 0, + time: 300, + }, 'ballistic2Under', 'fade'); + scene.showEffect('blackwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 0, + }, { + x: attacker.x - 50, + y: attacker.y - 50, + scale: 2, + opacity: 0, + time: 300, + }, 'ballistic'); + scene.showEffect('blackwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 150, + }, { + x: attacker.x + 60, + y: attacker.y - 50, + scale: 2, + opacity: 0, + time: 450, + }, 'ballistic'); + scene.showEffect('blackwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 300, + }, { + x: attacker.x + 10, + y: attacker.y - 60, + scale: 2, + opacity: 0, + time: 600, + }, 'ballistic'); + + scene.showEffect('flareball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.5, + time: 600, + }, { + scale: 4, + opacity: 0, + time: 900, + }, 'linear'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.5, + time: 800, + }, { + scale: 4, + opacity: 0, + time: 1100, + }, 'linear'); + + attacker.delay(300); + attacker.anim({ + x: defender.leftof(20), + y: defender.y, + z: defender.behind(-5), + time: 300, + }, 'accel'); + attacker.anim({ + time: 500, + }, 'ballistic2Back'); + defender.delay(580); + defender.anim({ + z: defender.behind(20), + time: 200, + }, 'decel'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, boltstrike: { anim(scene, [attacker, defender]) { scene.backgroundEffect('#00CCCC', 900, 0.3); @@ -11888,6 +13045,220 @@ export const BattleMoveAnims: AnimTable = { } }, }, + springtidestorm: { + anim(scene, [attacker, ...defenders]) { + scene.backgroundEffect('#FF99FF', 1000, 0.3); + + for (const defender of defenders) { + for (const effect of ['mistball', 'heart']) { + for (let i = 0; i < 4; i++) { + scene.showEffect(effect, { + x: defender.x + 50, + y: defender.y - 35, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x - 50, + y: defender.y, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + scene.showEffect(effect, { + x: defender.x - 50, + y: defender.y + 35, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x + 50, + y: defender.y, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + scene.showEffect(effect, { + x: defender.x + 50, + y: defender.y, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x - 50, + y: defender.y - 35, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + scene.showEffect(effect, { + x: defender.x - 50, + y: defender.y, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x + 50, + y: defender.y - 35, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + } + } + } + }, + }, + wildboltstorm: { + anim(scene, [attacker, ...defenders]) { + scene.backgroundEffect('#F6D434', 1000, 0.3); + + for (const defender of defenders) { + for (const effect of ['blackwisp', 'lightning']) { + for (let i = 0; i < 4; i++) { + scene.showEffect(effect, { + x: defender.x + 50, + y: defender.y - 35, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x - 50, + y: defender.y, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + scene.showEffect(effect, { + x: defender.x - 50, + y: defender.y + 35, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x + 50, + y: defender.y, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + scene.showEffect(effect, { + x: defender.x + 50, + y: defender.y, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x - 50, + y: defender.y - 35, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + scene.showEffect(effect, { + x: defender.x - 50, + y: defender.y, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x + 50, + y: defender.y - 35, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + } + } + } + }, + }, + sandsearstorm: { + anim(scene, [attacker, ...defenders]) { + scene.backgroundEffect('#B47F1F', 1000, 0.3); + + for (const defender of defenders) { + for (let i = 0; i < 4; i++) { + scene.showEffect('mudwisp', { + x: defender.x + 50, + y: defender.y - 35, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x - 50, + y: defender.y, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + scene.showEffect('mudwisp', { + x: defender.x - 50, + y: defender.y + 35, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x + 50, + y: defender.y, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + scene.showEffect('mudwisp', { + x: defender.x + 50, + y: defender.y, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x - 50, + y: defender.y - 35, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + scene.showEffect('mudwisp', { + x: defender.x - 50, + y: defender.y, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 200 * i, + }, { + x: defender.x + 50, + y: defender.y - 35, + z: defender.z, + scale: 0.4, + opacity: 0.4, + time: 200 * i + 200, + }, 'linear', 'fade'); + } + } + }, + }, ominouswind: { anim(scene, [attacker, defender]) { for (let i = 0; i < 3; i++) { @@ -13257,6 +14628,127 @@ export const BattleMoveAnims: AnimTable = { BattleOtherAnims.contactattack.anim(scene, [attacker, defender]); }, }, + aquastep: { + anim(scene, [attacker, defender]) { + BattleOtherAnims.dance.anim(scene, [attacker, defender]); + scene.showEffect('foot', { + x: defender.x, + y: defender.y - 30, + z: defender.behind(15), + scale: 1, + opacity: 1, + time: 550, + }, { + x: defender.x - 50, + z: defender.behind(20), + scale: 1.7, + opacity: 0, + time: 800, + }, 'linear'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y - 30, + z: defender.behind(15), + scale: 1, + opacity: 1, + time: 550, + }, { + x: defender.x - 50, + z: defender.behind(20), + scale: 1.7, + opacity: 0, + time: 800, + }, 'linear'); + }, + }, + aquacutter: { + anim(scene, [attacker, defender]) { + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1.5, + opacity: 0.6, + time: 700, + }, { + scale: 2, + opacity: 0, + time: 1000, + }, 'accel', 'fade'); + scene.showEffect('leftslash', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1.5, + opacity: 0.6, + time: 600, + }, { + scale: 2, + opacity: 0, + time: 1000, + }, 'accel', 'fade'); + scene.showEffect('iceball', { + x: defender.x - 60, + y: defender.y + 70, + z: defender.z, + scale: 0.75, + opacity: 1, + time: 400, + }, { + x: defender.x + 60, + y: defender.y - 70, + scale: 0.6, + opacity: 0, + time: 700, + }, 'decel'); + }, + }, + wavecrash: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('linear-gradient(#000039 30%, #3848B8)', 600, 0.6); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 300, + }, { + scale: 8, + opacity: 0, + time: 600, + }, 'linear'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 500, + }, { + scale: 8, + opacity: 0, + time: 800, + }, 'linear'); + attacker.anim({ + x: defender.x, + y: defender.y, + z: defender.behind(-5), + time: 300, + }, 'accel'); + attacker.anim({ + time: 500, + }, 'ballistic2Back'); + defender.delay(280); + defender.anim({ + z: defender.behind(20), + time: 100, + }, 'swing'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, crabhammer: { anim(scene, [attacker, defender]) { scene.showEffect('waterwisp', { @@ -14227,6 +15719,120 @@ export const BattleMoveAnims: AnimTable = { }, 'linear', 'explode'); }, }, + twinbeam: { + anim(scene, [attacker, defender]) { + scene.showEffect('mistball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.5, + opacity: 0.2, + }, { + x: defender.x, + y: defender.y, + z: defender.behind(20), + opacity: 0.6, + time: 200, + }, 'linear', 'explode'); + scene.showEffect('poisonwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.5, + opacity: 0.2, + time: 50, + }, { + x: defender.x + 10, + y: defender.y - 5, + z: defender.behind(20), + opacity: 0.6, + time: 250, + }, 'linear', 'explode'); + scene.showEffect('mistball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.5, + opacity: 0.2, + time: 100, + }, { + x: defender.x - 10, + y: defender.y + 5, + z: defender.behind(20), + opacity: 0.6, + time: 300, + }, 'linear', 'explode'); + scene.showEffect('poisonwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.5, + opacity: 0.2, + time: 150, + }, { + x: defender.x, + y: defender.y - 5, + z: defender.behind(20), + opacity: 0.6, + time: 350, + }, 'linear', 'explode'); + scene.showEffect('mistball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.5, + opacity: 0.2, + }, { + x: defender.x, + y: defender.y, + z: defender.behind(20), + opacity: 0.6, + time: 200, + }, 'linear', 'explode'); + scene.showEffect('poisonwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.5, + opacity: 0.2, + time: 450, + }, { + x: defender.x + 10, + y: defender.y - 5, + z: defender.behind(20), + opacity: 0.6, + time: 700, + }, 'linear', 'explode'); + scene.showEffect('mistball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.5, + opacity: 0.2, + time: 550, + }, { + x: defender.x - 10, + y: defender.y + 5, + z: defender.behind(20), + opacity: 0.6, + time: 750, + }, 'linear', 'explode'); + scene.showEffect('poisonwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.5, + opacity: 0.2, + time: 600, + }, { + x: defender.x, + y: defender.y - 5, + z: defender.behind(20), + opacity: 0.6, + time: 800, + }, 'linear', 'explode'); + }, + }, flamethrower: { anim(scene, [attacker, defender]) { scene.showEffect('fireball', { @@ -14304,6 +15910,54 @@ export const BattleMoveAnims: AnimTable = { }, 'ballistic', 'explode'); }, }, + spicyextract: { + anim(scene, [attacker, defender]) { + scene.showEffect('flarewisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.1, + opacity: 0, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.7, + opacity: 1, + time: 400, + }, 'ballistic', 'fade'); + scene.showEffect('flarewisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.1, + opacity: 0, + time: 100, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.7, + opacity: 1, + time: 500, + }, 'ballistic', 'fade'); + scene.showEffect('flarewisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.1, + opacity: 0, + time: 200, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.7, + opacity: 1, + time: 600, + }, 'ballistic', 'fade'); + }, + }, sludge: { anim(scene, [attacker, defender]) { scene.showEffect('poisonwisp', { @@ -15176,6 +16830,291 @@ export const BattleMoveAnims: AnimTable = { }, 'decel'); }, }, + triplearrows: { + anim(scene, [attacker, defender]) { + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 1, + opacity: 0.5, + }, { + scale: 6, + opacity: 0, + }, 'linear'); + scene.showEffect('wisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 1, + opacity: 0.5, + }, { + scale: 3, + opacity: 0.3, + time: 600, + }, 'decel', 'fade'); + + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y - 35, + z: attacker.z, + scale: 0.1, + opacity: 0.4, + time: 0, + }, { + x: attacker.x + 30, + y: attacker.y + 200, + z: attacker.z, + scale: 0.2, + opacity: 0, + time: 300, + }, 'decel'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y - 35, + z: attacker.z, + scale: 0.1, + opacity: 0.4, + time: 50, + }, { + x: attacker.x - 30, + y: attacker.y + 200, + z: attacker.z, + scale: 0.2, + opacity: 0, + time: 350, + }, 'decel'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y - 35, + z: attacker.z, + scale: 0.1, + opacity: 0.4, + time: 100, + }, { + x: attacker.x - 10, + y: attacker.y + 200, + z: attacker.z, + scale: 0.2, + opacity: 0, + time: 400, + }, 'decel'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y - 35, + z: attacker.z, + scale: 0.1, + opacity: 0.4, + time: 150, + }, { + x: attacker.x + 10, + y: attacker.y + 200, + z: attacker.z, + scale: 0.2, + opacity: 0, + time: 450, + }, 'decel'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y - 35, + z: attacker.z, + scale: 0.1, + opacity: 0.4, + time: 175, + }, { + x: attacker.x + 35, + y: attacker.y + 200, + z: attacker.z, + scale: 0.2, + opacity: 0, + time: 500, + }, 'decel', 'fade'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y - 35, + z: attacker.z, + scale: 0.1, + opacity: 0.4, + time: 200, + }, { + x: attacker.x, + y: attacker.y + 200, + z: attacker.behind(-10), + scale: 0.2, + opacity: 0, + time: 550, + }, 'decel', 'fade'); + + scene.showEffect('flareball', { + x: defender.x - 20, + y: defender.y + 200, + z: defender.behind(5), + opacity: 0.4, + xscale: 0.1, + yscale: 5, + time: 375, + }, { + y: defender.y + 150, + opacity: 0, + time: 675, + }, 'decel'); + scene.showEffect('flareball', { + x: defender.x - 20, + y: defender.y - 50, + z: defender.behind(5), + opacity: 0.4, + xscale: 0.3, + yscale: 0.1, + time: 390, + }, { + xscale: 0.6, + yscale: 0.1, + opacity: 0, + time: 675, + }, 'linear'); + + scene.showEffect('flareball', { + x: defender.x + 40, + y: defender.y + 200, + z: defender.behind(-5), + opacity: 0.4, + xscale: 0.1, + yscale: 5, + time: 525, + }, { + y: defender.y + 150, + opacity: 0, + time: 800, + }, 'decel'); + scene.showEffect('flareball', { + x: defender.x + 40, + y: defender.y - 50, + z: defender.behind(-5), + opacity: 0.4, + xscale: 0.3, + yscale: 0.1, + time: 540, + }, { + xscale: 0.6, + yscale: 0.1, + opacity: 0, + time: 800, + }, 'linear'); + + scene.showEffect('flareball', { + x: defender.x - 70, + y: defender.y + 200, + z: defender.behind(-10), + opacity: 0.4, + xscale: 0.1, + yscale: 5, + time: 575, + }, { + y: defender.y + 150, + z: defender.behind(-10), + opacity: 0, + time: 825, + }, 'decel'); + scene.showEffect('flareball', { + x: defender.x - 70, + y: defender.y - 50, + z: defender.z, + opacity: 0.4, + xscale: 0.3, + yscale: 0.1, + time: 590, + }, { + xscale: 0.6, + yscale: 0.1, + opacity: 0, + time: 825, + }, 'linear'); + + scene.showEffect('flareball', { + x: defender.x + 70, + y: defender.y + 200, + z: defender.behind(10), + opacity: 0.4, + xscale: 0.1, + yscale: 5, + time: 650, + }, { + y: defender.y + 150, + opacity: 0, + time: 950, + }, 'decel'); + scene.showEffect('flareball', { + x: defender.x + 70, + y: defender.y - 50, + z: defender.behind(10), + opacity: 0.4, + xscale: 0.3, + yscale: 0.1, + time: 665, + }, { + xscale: 0.6, + yscale: 0.1, + opacity: 0, + time: 950, + }, 'linear'); + + scene.showEffect('flareball', { + x: defender.x, + y: defender.y + 200, + z: defender.z, + opacity: 0.4, + xscale: 0.1, + yscale: 5, + time: 700, + }, { + y: defender.y + 150, + opacity: 0, + time: 1000, + }, 'decel'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y - 50, + z: defender.z, + opacity: 0.4, + xscale: 0.3, + yscale: 0.1, + time: 720, + }, { + xscale: 0.6, + yscale: 0.1, + opacity: 0, + time: 1000, + }, 'linear'); + + scene.showEffect('flareball', { + x: defender.x, + y: defender.y + 200, + z: defender.behind(-20), + opacity: 0.4, + xscale: 0.1, + yscale: 5, + time: 725, + }, { + y: defender.y + 150, + opacity: 0, + time: 1025, + }, 'decel'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y - 35, + z: defender.behind(-20), + opacity: 0.4, + xscale: 0.3, + yscale: 0.1, + time: 740, + }, { + xscale: 0.6, + yscale: 0.1, + opacity: 0, + time: 1025, + }, 'linear'); + }, + }, thousandarrows: { anim(scene, [attacker, ...defenders]) { for (const defender of defenders) { @@ -16485,6 +18424,75 @@ export const BattleMoveAnims: AnimTable = { }, 'accel'); }, }, + infernalparade: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('#BB59FF', 1000, 0.4); + + for (const axis of ['x', 'y', '']) { + scene.showEffect('shadowball', { + x: attacker.x + (axis !== 'y' ? 50 : 0), + y: attacker.y + (axis !== 'x' ? 50 : 0), + z: attacker.z, + scale: 0.5, + opacity: 0.5, + time: 0, + }, { + opacity: 0, + time: 600, + }, 'accel'); + scene.showEffect('bluefireball', { + x: attacker.x + (axis !== 'y' ? 50 : 0), + y: attacker.y + (axis !== 'x' ? 50 : 0), + z: attacker.z, + scale: 0.5, + opacity: 0.5, + time: 0, + }, { + opacity: 0, + time: 600, + }, 'accel'); + scene.showEffect('shadowball', { + x: attacker.x + (axis !== 'y' ? 50 : 0), + y: attacker.y + (axis !== 'x' ? 50 : 0), + z: attacker.z, + scale: 0.5, + opacity: 0, + time: 600, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1, + opacity: 0.5, + time: 1200, + }, 'accel'); + scene.showEffect('bluefireball', { + x: attacker.x + (axis !== 'y' ? 50 : 0), + y: attacker.y + (axis !== 'x' ? 50 : 0), + z: attacker.z, + scale: 0.5, + opacity: 0, + time: 600, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1, + opacity: 0.5, + time: 1200, + }, 'accel'); + } + + defender.delay(900); + defender.anim({ + z: defender.behind(10), + time: 200, + }, 'swing'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, darkpulse: { anim(scene, [attacker, defender]) { let xf = [1, -1, 1, -1]; @@ -16781,6 +18789,49 @@ export const BattleMoveAnims: AnimTable = { }, 'linear', 'fade'); }, }, + ruination: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('#000000', 800, 0.1); + scene.showEffect('shadowball', { + x: attacker.x, + y: attacker.y - 50, + z: attacker.z, + scale: 1, + xscale: 5, + opacity: 0.6, + time: 0, + }, { + scale: 2, + xscale: 8, + opacity: 0.1, + time: 300, + }, 'linear', 'fade'); + scene.showEffect('shadowball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 5, + opacity: 0, + time: 200, + }, { + scale: 0.5, + opacity: 0.6, + time: 600, + }, 'linear', 'fade'); + scene.showEffect('shadowball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 5, + opacity: 0, + time: 350, + }, { + scale: 0.5, + opacity: 0.2, + time: 800, + }, 'linear', 'fade'); + }, + }, energyball: { anim(scene, [attacker, defender]) { scene.showEffect('energyball', { @@ -17163,6 +19214,33 @@ export const BattleMoveAnims: AnimTable = { }, 'linear', 'explode'); }, }, + flowertrick: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect(`#000000`, 1000, 0.4); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.5, + opacity: 1, + }, { + y: attacker.y + 90, + opacity: 0, + }, 'linear'); + scene.showEffect('energyball', { + x: defender.x, + y: defender.y + 90, + z: defender.z, + scale: 0.5, + opacity: 0, + time: 500, + }, { + y: defender.y, + opacity: 1, + time: 1000, + }, 'linear', 'explode'); + }, + }, wish: { anim(scene, [attacker]) { scene.backgroundEffect(`url('https://${Config.routes.client}/fx/bg-space.jpg')`, 600, 0.4); @@ -17703,6 +19781,49 @@ export const BattleMoveAnims: AnimTable = { }, 'ballistic'); }, }, + mysticalpower: { + anim(scene, [attacker]) { + scene.showEffect('mistball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 0.5, + time: 0, + }, { + z: attacker.behind(-50), + scale: 7, + opacity: 0, + time: 400, + }, 'linear'); + scene.showEffect('mistball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 0.5, + time: 150, + }, { + z: attacker.behind(-50), + scale: 7, + opacity: 0, + time: 600, + }, 'linear'); + scene.showEffect('mistball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 0.5, + time: 300, + }, { + z: attacker.behind(-50), + scale: 7, + opacity: 0, + time: 800, + }, 'linear'); + }, + }, psyshock: { anim(scene, [attacker, defender]) { scene.showEffect('poisonwisp', { @@ -17739,6 +19860,99 @@ export const BattleMoveAnims: AnimTable = { }, 'decel'); }, }, + barbbarrage: { + anim(scene, [attacker, defender]) { + for (let i = 0; i < 8; i++) { + scene.showEffect('poisonwisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 0, + }, { + x: attacker.x + (![0, 4].includes(i) ? (50 * (i > 4 ? -1 : 1)) : 0), + y: attacker.y + (![2, 6].includes(i) ? (50 * (i > 2 && i < 6 ? -1 : 1)) : 0), + z: attacker.z, + opacity: 0, + time: 500, + }, 'decel'); + scene.showEffect('poisonwisp', { + x: defender.x + (![0, 4].includes(i) ? (50 * (i > 4 ? -1 : 1)) : 0), + y: defender.y + (![2, 6].includes(i) ? (50 * (i > 2 && i < 6 ? -1 : 1)) : 0), + z: defender.z, + scale: 0.4, + opacity: 0.6, + time: 500, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + time: 1000, + }, 'decel'); + } + }, + }, + esperwing: { + anim(scene, [attacker, defender]) { + for (let i = 0; i < 8; i++) { + scene.showEffect(i % 2 === 0 ? 'poisonwisp' : 'mistball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 0, + }, { + x: attacker.x + (![0, 4].includes(i) ? (50 * (i > 4 ? -1 : 1)) : 0), + y: attacker.y + (![2, 6].includes(i) ? (50 * (i > 2 && i < 6 ? -1 : 1)) : 0), + z: attacker.z, + opacity: 0, + time: 500, + }, 'decel'); + scene.showEffect('feather', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.2, + opacity: 0.6, + time: 0, + }, { + x: attacker.x + (![0, 4].includes(i) ? (50 * (i > 4 ? -1 : 1)) : 0), + y: attacker.y + (![2, 6].includes(i) ? (50 * (i > 2 && i < 6 ? -1 : 1)) : 0), + z: attacker.z, + opacity: 0, + time: 500, + }, 'decel'); + scene.showEffect(i % 2 === 0 ? 'poisonwisp' : 'mistball', { + x: attacker.x + (![0, 4].includes(i) ? (50 * (i > 4 ? -1 : 1)) : 0), + y: attacker.y + (![2, 6].includes(i) ? (50 * (i > 2 && i < 6 ? -1 : 1)) : 0), + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 500, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + time: 1000, + }, 'accel', 'explode'); + scene.showEffect('feather', { + x: attacker.x + (![0, 4].includes(i) ? (50 * (i > 4 ? -1 : 1)) : 0), + y: attacker.y + (![2, 6].includes(i) ? (50 * (i > 2 && i < 6 ? -1 : 1)) : 0), + z: attacker.z, + scale: 0.2, + opacity: 0.6, + time: 500, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + time: 1000, + }, 'accel', 'explode'); + } + }, + }, sandtomb: { anim(scene, [attacker, defender]) { scene.showEffect('mudwisp', { @@ -17775,6 +19989,42 @@ export const BattleMoveAnims: AnimTable = { }, 'decel'); }, }, + saltcure: { + anim(scene, [attacker, defender]) { + scene.showEffect('wisp', { + x: defender.x + 40, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 0.6, + }, { + scale: 3, + opacity: 0, + }, 'decel'); + scene.showEffect('wisp', { + x: defender.x - 40, + y: defender.y - 20, + z: defender.z, + scale: 0, + opacity: 0.6, + time: 150, + }, { + scale: 3, + opacity: 0, + }, 'decel'); + scene.showEffect('wisp', { + x: defender.x + 10, + y: defender.y + 20, + z: defender.z, + scale: 0, + opacity: 0.6, + time: 300, + }, { + scale: 3, + opacity: 0, + }, 'decel'); + }, + }, flashcannon: { anim(scene, [attacker, defender]) { scene.showEffect('wisp', { @@ -18481,6 +20731,65 @@ export const BattleMoveAnims: AnimTable = { }); }, }, + makeitrain: { + anim(scene, [attacker, defender]) { + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 2, + opacity: 0, + }, { + scale: 0, + opacity: 1, + }, 'accel', 'explode'); + + for (let i = 1; i <= 3; i++) { + scene.showEffect('electroball', { + x: attacker.x - 10, + y: attacker.y + 25, + z: attacker.z, + scale: 0.1, + opacity: 1, + time: 500 * i, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 0, + time: 500 * i + 100, + }, 'decel'); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.1, + opacity: 1, + time: 600 * i, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 0, + time: 600 * i + 100, + }, 'accel'); + scene.showEffect('electroball', { + x: attacker.x + 10, + y: attacker.y - 25, + z: attacker.z, + scale: 0.1, + opacity: 1, + time: 700 * i, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 0, + time: 700 * i + 100, + }, 'accel'); + } + }, + }, brine: { anim: BattleOtherAnims.hydroshot.anim, }, @@ -26394,6 +28703,347 @@ export const BattleMoveAnims: AnimTable = { }); }, }, + collisioncourse: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-sunnyday.jpg')`, 1300, 0.5); + scene.showEffect(attacker.sp, { + x: attacker.x, + y: attacker.y, + z: attacker.z, + opacity: 0.3, + time: 25, + }, { + y: attacker.y + 150, + opacity: 0, + time: 325, + }, 'decel'); + scene.showEffect(attacker.sp, { + x: attacker.x, + y: attacker.y + 150, + z: attacker.z, + opacity: 0.3, + time: 625, + }, { + x: defender.leftof(-10), + y: defender.y + 5, + z: defender.behind(10), + opacity: 0, + time: 825, + }, 'decel'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y + 150, + z: attacker.z, + scale: 1, + opacity: 0.6, + time: 600, + }, { + x: defender.leftof(-10), + y: defender.y + 5, + z: defender.behind(10), + opacity: 0.3, + time: 800, + }, 'accel', 'explode'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y + 150, + z: attacker.behind(-50), + scale: 1, + opacity: 0.5, + time: 600, + }, { + x: defender.leftof(-10), + y: defender.y + 5, + z: defender.behind(10), + opacity: 0.6, + time: 800, + }, 'accel', 'explode'); + + scene.showEffect('flareball', { + x: defender.x, + y: defender.y - 60, + z: defender.z, + scale: 1, + xscale: 3, + opacity: 1, + time: 850, + }, { + scale: 2, + xscale: 12, + opacity: 0, + time: 1250, + }, 'linear', 'fade'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 0.7, + scale: 1, + time: 850, + }, { + scale: 6, + opacity: 0, + time: 1400, + }, 'linear'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y + 350, + z: defender.z, + opacity: 1, + scale: 3, + yscale: 10, + time: 850, + }, { + xscale: 0, + time: 1500, + }, 'accel', 'fade'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 1, + scale: 3, + time: 850, + }, { + scale: 9, + time: 1400, + }, 'linear', 'explode'); + + attacker.anim({ + x: attacker.x, + y: attacker.y + 250, + z: attacker.z, + time: 300, + }, 'decel'); + attacker.delay(300); + attacker.anim({ + x: defender.leftof(-10), + y: defender.y + 5, + z: defender.behind(10), + opacity: 1, + time: 200, + }, 'ballistic2Under'); + attacker.delay(50); + attacker.anim({ + opacity: 0, + time: 1, + }); + attacker.delay(700); + attacker.anim({ + opacity: 1, + time: 200, + }); + defender.delay(650); + defender.anim({ + y: defender.y - 10, + z: defender.behind(5), + time: 50, + }, 'swing'); + defender.anim({ + y: defender.y - 20, + z: defender.behind(20), + time: 200, + }, 'swing'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, + electrodrift: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect(`url('https://${Config.routes.client}/fx/weather-electricterrain.png')`, 1300, 0.5); + scene.showEffect(attacker.sp, { + x: attacker.x, + y: attacker.y, + z: attacker.z, + opacity: 0.3, + time: 25, + }, { + y: attacker.y + 150, + opacity: 0, + time: 325, + }, 'decel'); + scene.showEffect(attacker.sp, { + x: attacker.x, + y: attacker.y + 150, + z: attacker.z, + opacity: 0.3, + time: 625, + }, { + x: defender.leftof(-10), + y: defender.y + 5, + z: defender.behind(10), + opacity: 0, + time: 825, + }, 'decel'); + scene.showEffect('waterwisp', { + x: attacker.x, + y: attacker.y + 150, + z: attacker.z, + scale: 1, + opacity: 0.6, + time: 600, + }, { + x: defender.leftof(-10), + y: defender.y + 5, + z: defender.behind(10), + opacity: 0.3, + time: 800, + }, 'accel', 'explode'); + scene.showEffect('waterwisp', { + x: attacker.x, + y: attacker.y + 150, + z: attacker.behind(-50), + scale: 1, + opacity: 0.5, + time: 600, + }, { + x: defender.leftof(-10), + y: defender.y + 5, + z: defender.behind(10), + opacity: 0.6, + time: 800, + }, 'accel', 'explode'); + + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y - 60, + z: defender.z, + scale: 1, + xscale: 3, + opacity: 1, + time: 850, + }, { + scale: 2, + xscale: 12, + opacity: 0, + time: 1250, + }, 'linear', 'fade'); + scene.showEffect('lightning', { + x: defender.x, + y: defender.y - 60, + z: defender.z, + scale: 1, + xscale: 3, + opacity: 1, + time: 850, + }, { + scale: 2, + xscale: 12, + opacity: 0, + time: 1250, + }, 'linear', 'fade'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 0.7, + scale: 1, + time: 850, + }, { + scale: 6, + opacity: 0, + time: 1400, + }, 'linear'); + scene.showEffect('lightning', { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 0.7, + scale: 1, + time: 850, + }, { + scale: 6, + opacity: 0, + time: 1400, + }, 'linear'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y + 350, + z: defender.z, + opacity: 1, + scale: 3, + yscale: 10, + time: 850, + }, { + xscale: 0, + time: 1500, + }, 'accel', 'fade'); + scene.showEffect('lightning', { + x: defender.x, + y: defender.y + 350, + z: defender.z, + opacity: 1, + scale: 3, + yscale: 10, + time: 850, + }, { + xscale: 0, + time: 1500, + }, 'accel', 'fade'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 1, + scale: 3, + time: 850, + }, { + scale: 9, + time: 1400, + }, 'linear', 'explode'); + scene.showEffect('lightning', { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 1, + scale: 3, + time: 850, + }, { + scale: 9, + time: 1400, + }, 'linear', 'explode'); + + attacker.anim({ + x: attacker.x, + y: attacker.y + 250, + z: attacker.z, + time: 300, + }, 'decel'); + attacker.delay(300); + attacker.anim({ + x: defender.leftof(-10), + y: defender.y + 5, + z: defender.behind(10), + opacity: 1, + time: 200, + }, 'ballistic2Under'); + attacker.delay(50); + attacker.anim({ + opacity: 0, + time: 1, + }); + attacker.delay(700); + attacker.anim({ + opacity: 1, + time: 200, + }); + defender.delay(650); + defender.anim({ + y: defender.y - 10, + z: defender.behind(5), + time: 50, + }, 'swing'); + defender.anim({ + y: defender.y - 20, + z: defender.behind(20), + time: 200, + }, 'swing'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, sunsteelstrike: { anim(scene, [attacker, defender]) { let xstep = (defender.x - attacker.x) / 5; @@ -32468,4 +35118,40 @@ BattleMoveAnims['shellsidearmspecial'] = {anim: BattleMoveAnims['sludgebomb'].an BattleMoveAnims['surgingstrikes'] = {anim: BattleMoveAnims['aquajet'].anim}; BattleMoveAnims['eeriespell'] = {anim: BattleMoveAnims['psyshock'].anim}; +BattleMoveAnims['axekick'] = {anim: BattleMoveAnims['highjumpkick'].anim}; +BattleMoveAnims['bittermalice'] = {anim: BattleMoveAnims['spectralthief'].anim}; +BattleMoveAnims['bleakwindstorm'] = {anim: BattleMoveAnims['hurricane'].anim}; +BattleMoveAnims['ceaselessedge'] = {anim: BattleMoveAnims['nightslash'].anim}; +BattleMoveAnims['chillingwater'] = {anim: BattleMoveAnims['waterpulse'].anim}; +BattleMoveAnims['comeuppance'] = {anim: BattleMoveAnims['darkpulse'].anim}; +BattleMoveAnims['doubleshock'] = {anim: BattleMoveAnims['wildcharge'].anim}; +BattleMoveAnims['filletaway'] = {anim: BattleMoveAnims['bulkup'].anim}; +BattleMoveAnims['glaiverush'] = {anim: BattleMoveAnims['outrage'].anim}; +BattleMoveAnims['headlongrush'] = { + anim(scene, [attacker, defender]) { + BattleMoveAnims['closecombat'].anim(scene, [attacker, defender]); + BattleMoveAnims['earthpower'].anim(scene, [attacker, defender]); + }, +}; +BattleMoveAnims['hyperdrill'] = {anim: BattleMoveAnims['drillrun'].anim}; +BattleMoveAnims['kowtowcleave'] = {anim: BattleMoveAnims['nightslash'].anim}; +BattleMoveAnims['lastrespects'] = {anim: BattleMoveAnims['memento'].anim}; +BattleMoveAnims['luminacrash'] = {anim: BattleMoveAnims['esperwing'].anim}; +BattleMoveAnims['lunarblessing'] = {anim: BattleMoveAnims['moonlight'].anim}; +BattleMoveAnims['mountaingale'] = {anim: BattleMoveAnims['powergem'].anim}; +BattleMoveAnims['pounce'] = {anim: BattleMoveAnims['bodyslam'].anim}; +BattleMoveAnims['powershift'] = {anim: BattleMoveAnims['skillswap'].anim}; +BattleMoveAnims['ragefist'] = {anim: BattleMoveAnims['shadowpunch'].anim}; +BattleMoveAnims['ragingbull'] = {anim: BattleMoveAnims['gigaimpact'].anim}; BattleMoveAnims['shedtail'] = {anim: BattleMoveAnims['substitute'].anim}; +BattleMoveAnims['shelter'] = {anim: BattleMoveAnims['withdraw'].anim}; +BattleMoveAnims['stoneaxe'] = { + anim(scene, [attacker, defender]) { + BattleMoveAnims['stoneedge'].anim(scene, [attacker, defender]); + BattleOtherAnims.slashattack.anim(scene, [attacker, defender]); + }, +}; +BattleMoveAnims['terablast'] = {anim: BattleMoveAnims['swift'].anim}; // placeholder +BattleMoveAnims['tidyup'] = {anim: BattleMoveAnims['bulkup'].anim}; +BattleMoveAnims['trailblaze'] = {anim: BattleMoveAnims['powerwhip'].anim}; +BattleMoveAnims['tripledive'] = {anim: BattleMoveAnims['dive'].anim}; diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 4486e6a087..871b8f5a59 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -2569,7 +2569,7 @@ export class PokemonSprite extends Sprite { return; } const spriten = +this.isFrontSprite; - if (id === 'substitute') { + if (id === 'substitute' || id === 'shedtail') { this.animSub(instant); } else if (id === 'leechseed') { const pos1 = { diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 647be428ed..353001fa83 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -837,7 +837,8 @@ class BattleTextParser { if (id === 'celebrate') { return this.template('activate', 'celebrate').replace('[TRAINER]', this.trainer(pokemon.slice(0, 2))); } - if (!target && ['hyperspacefury', 'hyperspacehole', 'phantomforce', 'shadowforce', 'feint'].includes(id)) { + if (!target && + ['hyperdrill', 'hyperspacefury', 'hyperspacehole', 'phantomforce', 'shadowforce', 'feint'].includes(id)) { [pokemon, target] = [kwArgs.of, pokemon]; if (!pokemon) pokemon = target; } diff --git a/src/battle.ts b/src/battle.ts index 19fe2289dc..94febc5fd6 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2846,6 +2846,7 @@ export class Battle { target!.side.removeSideCondition('Reflect'); target!.side.removeSideCondition('LightScreen'); break; + case 'hyperdrill': case 'hyperspacefury': case 'hyperspacehole': case 'phantomforce': From 49443882814b54c9c306bb63f7c9edbcc8909777 Mon Sep 17 00:00:00 2001 From: Hisuian Zoroark <96159984+HisuianZoroark@users.noreply.github.com> Date: Sat, 10 Dec 2022 18:08:45 -0500 Subject: [PATCH 357/770] Teambuilder: Fix import from Pokepaste (#2044) --- js/client-teambuilder.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 883adb0b7f..48fda25b85 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -1309,9 +1309,8 @@ url: url, success: function (data) { if (/^https?:\/\/pokepast\.es\/.*\/json\s*$/.test(url)) { - var teamData = JSON.parse(data); - var notes = teamData.notes.split('\n'); + var notes = data.notes.split('\n'); if (notes[0].startsWith('Format: ')) { var formatid = toID(notes[0].slice(8)); var format = window.BattleFormats && window.BattleFormats[formatid]; @@ -1320,13 +1319,13 @@ } var teamNotes = notes.join('\n'); // Not implemented yet - var title = teamData.title; + var title = data.title; if (title && !title.startsWith('Untitled')) { title = title.replace(/[\|\\\/]/g, ''); self.$('.teamnameedit').val(title).change(); } - Storage.activeSetList = self.curSetList = Storage.importTeam(teamData.paste); + Storage.activeSetList = self.curSetList = Storage.importTeam(data.paste); } else { Storage.activeSetList = self.curSetList = Storage.importTeam(data); } From 0d9caf6f6298e34c30afe1a5090f818f9df73c13 Mon Sep 17 00:00:00 2001 From: Marty Date: Tue, 13 Dec 2022 13:44:44 -0500 Subject: [PATCH 358/770] Update Pokemon icons sheet --- src/battle-dex-data.ts | 4 ++++ src/battle-dex.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index bab4849613..ba3c27c150 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -380,6 +380,9 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { squawkabillyyellow: 1020 + 234, squawkabillywhite: 1020 + 235, gimmighoulroaming: 1020 + 236, + dialgaorigin: 1020 + 237, + palkiaorigin: 1020 + 238, + basculinwhitestriped: 1020 + 239, gumshoostotem: 735, raticatealolatotem: 1020 + 120, @@ -550,6 +553,7 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { solotl: 1488 + 31, miasmite: 1488 + 32, dorsoil: 1488 + 33, + saharascal: 1488 + 34, }; const BattlePokemonIconIndexesLeft: {[id: string]: number} = { diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 7799ef97db..75033860bd 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -726,7 +726,7 @@ const Dex = new class implements ModdedDex { let top = Math.floor(num / 12) * 30; let left = (num % 12) * 40; let fainted = ((pokemon as Pokemon | ServerPokemon)?.fainted ? `;opacity:.3;filter:grayscale(100%) brightness(.5)` : ``); - return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v9) no-repeat scroll -${left}px -${top}px${fainted}`; + return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v10) no-repeat scroll -${left}px -${top}px${fainted}`; } getTeambuilderSpriteData(pokemon: any, gen: number = 0): TeambuilderSpriteData { From e338a93dad0d47d1c837a1bf926459329db44bcc Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Tue, 13 Dec 2022 11:47:46 -0700 Subject: [PATCH 359/770] Fix Spicy Extract and Make It Rain animations (#2047) --- src/battle-animations-moves.ts | 106 +++++++++++++++++---------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/src/battle-animations-moves.ts b/src/battle-animations-moves.ts index d2073f4261..6562e0c096 100644 --- a/src/battle-animations-moves.ts +++ b/src/battle-animations-moves.ts @@ -15912,7 +15912,7 @@ export const BattleMoveAnims: AnimTable = { }, spicyextract: { anim(scene, [attacker, defender]) { - scene.showEffect('flarewisp', { + scene.showEffect('flareball', { x: attacker.x, y: attacker.y, z: attacker.z, @@ -15926,7 +15926,7 @@ export const BattleMoveAnims: AnimTable = { opacity: 1, time: 400, }, 'ballistic', 'fade'); - scene.showEffect('flarewisp', { + scene.showEffect('flareball', { x: attacker.x, y: attacker.y, z: attacker.z, @@ -15941,7 +15941,7 @@ export const BattleMoveAnims: AnimTable = { opacity: 1, time: 500, }, 'ballistic', 'fade'); - scene.showEffect('flarewisp', { + scene.showEffect('flareball', { x: attacker.x, y: attacker.y, z: attacker.z, @@ -20732,61 +20732,63 @@ export const BattleMoveAnims: AnimTable = { }, }, makeitrain: { - anim(scene, [attacker, defender]) { - scene.showEffect('electroball', { - x: attacker.x, - y: attacker.y, - z: attacker.z, - scale: 2, - opacity: 0, - }, { - scale: 0, - opacity: 1, - }, 'accel', 'explode'); - - for (let i = 1; i <= 3; i++) { - scene.showEffect('electroball', { - x: attacker.x - 10, - y: attacker.y + 25, - z: attacker.z, - scale: 0.1, - opacity: 1, - time: 500 * i, - }, { - x: defender.x, - y: defender.y, - z: defender.z, - opacity: 0, - time: 500 * i + 100, - }, 'decel'); + anim(scene, [attacker, ...defenders]) { + for (const defender of defenders) { scene.showEffect('electroball', { x: attacker.x, y: attacker.y, z: attacker.z, - scale: 0.1, - opacity: 1, - time: 600 * i, - }, { - x: defender.x, - y: defender.y, - z: defender.z, + scale: 2, opacity: 0, - time: 600 * i + 100, - }, 'accel'); - scene.showEffect('electroball', { - x: attacker.x + 10, - y: attacker.y - 25, - z: attacker.z, - scale: 0.1, - opacity: 1, - time: 700 * i, }, { - x: defender.x, - y: defender.y, - z: defender.z, - opacity: 0, - time: 700 * i + 100, - }, 'accel'); + scale: 0, + opacity: 1, + }, 'accel', 'explode'); + + for (let i = 1; i <= 3; i++) { + scene.showEffect('electroball', { + x: attacker.x - 10, + y: attacker.y + 25, + z: attacker.z, + scale: 0.1, + opacity: 1, + time: 500 * i, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 0, + time: 500 * i + 100, + }, 'decel'); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.1, + opacity: 1, + time: 600 * i, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 0, + time: 600 * i + 100, + }, 'accel'); + scene.showEffect('electroball', { + x: attacker.x + 10, + y: attacker.y - 25, + z: attacker.z, + scale: 0.1, + opacity: 1, + time: 700 * i, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + opacity: 0, + time: 700 * i + 100, + }, 'accel'); + } } }, }, From cf1f7b6bee5041262d247e5a8138b7774b8b9767 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Tue, 13 Dec 2022 11:48:40 -0700 Subject: [PATCH 360/770] Add more support for undefined effect tags (#2048) --- src/battle-animations.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 871b8f5a59..e90ee6a6d8 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -2781,7 +2781,19 @@ export class PokemonSprite extends Sprite { let effect = PokemonSprite.statusTable[id]; if (typeof effect === 'string') return effect; if (effect === null) return PokemonSprite.statusTable[id] = ''; - if (effect === undefined) effect = [`[[${id}]]`, 'neutral']; + if (effect === undefined) { + let label = `[[${id}]]`; + if (Dex.species.get(id).exists) { + label = Dex.species.get(id).name; + } else if (Dex.items.get(id).exists) { + label = Dex.items.get(id).name; + } else if (Dex.moves.get(id).exists) { + label = Dex.moves.get(id).name; + } else if (Dex.abilities.get(id).exists) { + label = Dex.abilities.get(id).name; + } + effect = [label, 'neutral']; + } return PokemonSprite.statusTable[id] = `${effect[0].replace(/ /g, ' ')} `; } From 67d8c83fc75476f234365bbfc9e3ec8f2d6702d3 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Tue, 13 Dec 2022 13:48:58 -0500 Subject: [PATCH 361/770] Fix Blizzard not showing 100% accuracy in Snow (#2049) --- src/battle-tooltips.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 8576c24685..ecc090f36f 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -28,7 +28,7 @@ class ModifiableValue { this.itemName = Dex.items.get(serverPokemon.item).name; const ability = serverPokemon.ability || pokemon?.ability || serverPokemon.baseAbility; this.abilityName = Dex.abilities.get(ability).name; - this.weatherName = Dex.moves.get(battle.weather).exists ? + this.weatherName = battle.weather === 'snow' ? 'Snow' : Dex.moves.get(battle.weather).exists ? Dex.moves.get(battle.weather).name : Dex.abilities.get(battle.weather).name; } reset(value = 0, isAccuracy?: boolean) { From ca186e1c4c1f9c6f68a498fefae9765e7e23c91c Mon Sep 17 00:00:00 2001 From: Adam Tran Date: Tue, 13 Dec 2022 13:49:43 -0500 Subject: [PATCH 362/770] Fix Rage Fist counter triggering from Substitute (#2050) --- src/battle.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/battle.ts b/src/battle.ts index 94febc5fd6..29fab50650 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1686,7 +1686,9 @@ export class Battle { break; } } else { - poke.timesAttacked += 1; + if (this.dex.moves.get(this.lastMove).category !== 'Status') { + poke.timesAttacked++; + } let damageinfo = '' + Pokemon.getFormattedRange(range, damage[1] === 100 ? 0 : 1, '\u2013'); if (damage[1] !== 100) { let hover = '' + ((damage[0] < 0) ? '\u2212' : '') + From 6e5e5e4cd1d8962516928a2e8ce55a2a6370cce5 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Tue, 13 Dec 2022 12:50:27 -0600 Subject: [PATCH 363/770] Revert "Tooltips: Make Ruin abilities stack (#2035)" (#2052) This reverts commit 9f42e01b87771656cac5b8ccc45a0c1a3584e638. --- src/battle-tooltips.ts | 16 ++++++++++++---- src/battle.ts | 15 +++------------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index ecc090f36f..070e08529a 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1208,10 +1208,18 @@ class BattleTooltips { if (ability === 'furcoat') { stats.def *= 2; } - stats.spa = Math.floor(stats.spa * Math.pow(0.75, this.battle.abilityActive('Vessel of Ruin', clientPokemon))); - stats.def = Math.floor(stats.def * Math.pow(0.75, this.battle.abilityActive('Sword of Ruin', clientPokemon))); - stats.atk = Math.floor(stats.atk * Math.pow(0.75, this.battle.abilityActive('Tablets of Ruin', clientPokemon))); - stats.spd = Math.floor(stats.spd * Math.pow(0.75, this.battle.abilityActive('Beads of Ruin', clientPokemon))); + if (this.battle.abilityActive('Vessel of Ruin', clientPokemon)) { + stats.spa = Math.floor(stats.spa * 0.75); + } + if (this.battle.abilityActive('Sword of Ruin', clientPokemon)) { + stats.def = Math.floor(stats.def * 0.75); + } + if (this.battle.abilityActive('Tablets of Ruin', clientPokemon)) { + stats.atk = Math.floor(stats.atk * 0.75); + } + if (this.battle.abilityActive('Beads of Ruin', clientPokemon)) { + stats.spd = Math.floor(stats.spd * 0.75); + } const sideConditions = this.battle.mySide.sideConditions; if (sideConditions['tailwind']) { speedModifiers.push(2); diff --git a/src/battle.ts b/src/battle.ts index 29fab50650..52aa639c42 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1190,28 +1190,19 @@ export class Battle { } return false; } - /** - * Returns 1 if the abilities are active and 0 if none are active. If `excludePokemon` was provided, instead - * returns the number of active sources of the abilities. - * @param abilities A string or array of strings containing the name or names of abilities to look for. - * @param excludePokemon A Pokemon to be ignored if the ability/abilities do not affect their source, - * i.e. Sword of Ruin. - */ abilityActive(abilities: string | string[], excludePokemon?: Pokemon | null) { - let activeAbilityCount = 0; if (typeof abilities === 'string') abilities = [abilities]; if (this.ngasActive()) { abilities = abilities.filter(a => this.dex.abilities.get(a).isPermanent); - if (!abilities.length) return 0; + if (!abilities.length) return false; } for (const active of this.getAllActive()) { if (active === excludePokemon) continue; if (abilities.includes(active.ability) && !active.volatiles['gastroacid']) { - if (!excludePokemon) return 1; - activeAbilityCount++; + return true; } } - return activeAbilityCount; + return false; } reset() { this.paused = true; From 32c43be01e54765d9a0a0e3ea5abaaf9f4dc35ee Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Tue, 13 Dec 2022 22:18:00 -0700 Subject: [PATCH 364/770] Make [Gen 9] Random Battle the default format (#2054) --- js/client-mainmenu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index 721edd874d..a476a38db2 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -994,8 +994,8 @@ if (!noChoice) { this.curFormat = formatid; if (!this.curFormat) { - if (BattleFormats['gen8randombattle']) { - this.curFormat = 'gen8randombattle'; + if (BattleFormats['gen9randombattle']) { + this.curFormat = 'gen9randombattle'; } else for (var i in BattleFormats) { if (!BattleFormats[i].searchShow || !BattleFormats[i].challengeShow) continue; this.curFormat = i; From f28d3affc93ad4b222e091930b55dcc1f4caf848 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Thu, 15 Dec 2022 18:46:24 -0600 Subject: [PATCH 365/770] Add a scroll message type for pages (#2055) --- js/client-ladder.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/js/client-ladder.js b/js/client-ladder.js index b5d4c46b69..89547a6b7d 100644 --- a/js/client-ladder.js +++ b/js/client-ladder.js @@ -62,6 +62,16 @@ this.subtleNotifyOnce(); break; + case 'scroll': + if (!row[1]) return; + var target = this.$(row[1]).get(0); + if (target) { + // normally i'd use jquery but jquery's scroll is more finicky + // and less consistent. + // This brings it into view centered every time + target.scrollIntoView(); + } + break; case 'notify': app.playNotificationSound(); this.notifyOnce(row[1], row[2], 'highlight'); From f6d95b22b44c37937db67011b30ab571058ce66a Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Thu, 15 Dec 2022 19:56:09 -0600 Subject: [PATCH 366/770] Battle-log: Whitelist a data- attribute for server-side divs (#2056) This is necessary for a custom identifier for the |scroll| message type. I originally wanted data-time to sort out timestamps, but I figured this would be a better all-use attribute that other server pages could use to identify divs for scrolling to / other selector stuff (Caja sanitizes out data-* attribs otherwise) --- src/battle-log.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle-log.ts b/src/battle-log.ts index a45b6c9c16..83d66c6fa6 100644 --- a/src/battle-log.ts +++ b/src/battle-log.ts @@ -750,6 +750,7 @@ export class BattleLog { 'psicon::category': 0, 'username::name': 0, 'form::data-submitsend': 0, + 'div::data-server': 0, 'button::data-send': 0, 'form::data-delimiter': 0, 'button::data-delimiter': 0, From 2f88e632061a9fa07300d7fe8ff724da0e8d1b16 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Fri, 16 Dec 2022 12:50:56 -0500 Subject: [PATCH 367/770] Add Open Team Sheet PokePaste button to VGC formats (#2057) --- js/client-teambuilder.js | 22 +++++--- js/storage.js | 114 ++++++++++++++++++++------------------- 2 files changed, 73 insertions(+), 63 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 48fda25b85..a389c98b21 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -830,13 +830,18 @@ this.exportMode = true; this.update(); }, - pokepasteExport: function () { - var team = Storage.exportTeam(this.curSetList); + pokepasteExport: function (type) { + var team = Storage.exportTeam(this.curSetList, this.curTeam.gen, type === 'openteamsheet'); if (!team) return app.addPopupMessage("Add a Pokémon to your team before uploading it!"); document.getElementById("pasteData").value = team; document.getElementById("pasteTitle").value = this.curTeam.name; + if (type === 'openteamsheet') { + document.getElementById("pasteTitle").value += " (OTS)"; + } document.getElementById("pasteAuthor").value = app.user.get('name'); - if (this.curTeam.format !== 'gen9') document.getElementById("pasteNotes").value = "Format: " + this.curTeam.format; + if (this.curTeam.format !== 'gen9') { + document.getElementById("pasteNotes").value = "Format: " + this.curTeam.format; + } document.getElementById("pokepasteForm").submit(); }, @@ -867,7 +872,7 @@ // Chrome is dumb and doesn't support data URLs in HTTPS urlprefix = "https://" + Config.routes.client + "/action.php?act=dlteam&team="; } - var contents = Storage.exportTeam(team.team).replace(/\n/g, '\r\n'); + var contents = Storage.exportTeam(team.team, team.gen).replace(/\n/g, '\r\n'); var downloadurl = "text/plain:" + filename + ":" + urlprefix + encodeURIComponent(window.btoa(unescape(encodeURIComponent(contents)))); console.log(downloadurl); dataTransfer.setData("DownloadURL", downloadurl); @@ -1109,7 +1114,7 @@ var buf = ''; if (this.exportMode) { buf = '
        '; - buf += '
        '; + buf += '
        '; } else { buf = '
        '; buf += ' '; @@ -1158,6 +1163,9 @@ buf += ''; buf += ''; buf += ''; + if (this.curTeam.format.includes('vgc')) { + buf += ''; + } buf += '
        '; } this.$el.html('
        ' + buf + '
        '); @@ -1634,7 +1642,7 @@ this.$('.teambuilder-pokemon-import') .show() .find('textarea') - .val(Storage.exportTeam([this.curSet]).trim()) + .val(Storage.exportTeam([this.curSet], this.curTeam.gen).trim()) .focus() .select(); @@ -1692,7 +1700,7 @@ var smogonSet = formatSets['dex'][species][setName] || formatSets['stats'][species][setName]; var curSet = $.extend({}, this.curSet, smogonSet); - var text = Storage.exportTeam([curSet]); + var text = Storage.exportTeam([curSet], this.curTeam.gen); this.$('.teambuilder-pokemon-import .pokemonedit').val(text); }, closePokemonImport: function (force) { diff --git a/js/storage.js b/js/storage.js index 6fd23a3d29..7070c0020d 100644 --- a/js/storage.js +++ b/js/storage.js @@ -1268,7 +1268,7 @@ Storage.exportAllTeams = function () { for (var i = 0, len = Storage.teams.length; i < len; i++) { var team = Storage.teams[i]; buf += '=== ' + (team.format ? '[' + team.format + (team.capacity === 24 ? '-box] ' : '] ') : '') + (team.folder ? '' + team.folder + '/' : '') + team.name + ' ===\n\n'; - buf += Storage.exportTeam(team.team); + buf += Storage.exportTeam(team.team, team.gen); buf += '\n'; } return buf; @@ -1279,13 +1279,13 @@ Storage.exportFolder = function (folder) { var team = Storage.teams[i]; if (team.folder + "/" === folder || team.format === folder) { buf += '=== ' + (team.format ? '[' + team.format + (team.capacity === 24 ? '-box] ' : '] ') : '') + (team.folder ? '' + team.folder + '/' : '') + team.name + ' ===\n\n'; - buf += Storage.exportTeam(team.team); + buf += Storage.exportTeam(team.team, team.gen); buf += '\n'; } } return buf; }; -Storage.exportTeam = function (team) { +Storage.exportTeam = function (team, gen, hidestats) { if (!team) return ""; if (typeof team === 'string') { if (team.indexOf('\n') >= 0) return team; @@ -1329,72 +1329,74 @@ Storage.exportTeam = function (team) { if (curSet.gigantamax) { text += 'Gigantamax: Yes \n'; } - if (curSet.teraType) { - text += 'Tera Type: ' + curSet.teraType + " \n"; + if (gen === 9) { + text += 'Tera Type: ' + (curSet.teraType || Dex.species.get(curSet.species).types[0]) + " \n"; } - var first = true; - if (curSet.evs) { - for (var j in BattleStatNames) { - if (!curSet.evs[j]) continue; - if (first) { - text += 'EVs: '; - first = false; - } else { - text += ' / '; + if (!hidestats) { + var first = true; + if (curSet.evs) { + for (var j in BattleStatNames) { + if (!curSet.evs[j]) continue; + if (first) { + text += 'EVs: '; + first = false; + } else { + text += ' / '; + } + text += '' + curSet.evs[j] + ' ' + BattleStatNames[j]; } - text += '' + curSet.evs[j] + ' ' + BattleStatNames[j]; } - } - if (!first) { - text += " \n"; - } - if (curSet.nature) { - text += '' + curSet.nature + ' Nature' + " \n"; - } - var first = true; - if (curSet.ivs) { - var defaultIvs = true; - var hpType = false; - for (var j = 0; j < curSet.moves.length; j++) { - var move = curSet.moves[j]; - if (move.substr(0, 13) === 'Hidden Power ' && move.substr(0, 14) !== 'Hidden Power [') { - hpType = move.substr(13); - if (!Dex.types.isName(hpType)) { - alert(move + " is not a valid Hidden Power type."); - continue; + if (!first) { + text += " \n"; + } + if (curSet.nature) { + text += '' + curSet.nature + ' Nature' + " \n"; + } + var first = true; + if (curSet.ivs) { + var defaultIvs = true; + var hpType = false; + for (var j = 0; j < curSet.moves.length; j++) { + var move = curSet.moves[j]; + if (move.substr(0, 13) === 'Hidden Power ' && move.substr(0, 14) !== 'Hidden Power [') { + hpType = move.substr(13); + if (!Dex.types.isName(hpType)) { + alert(move + " is not a valid Hidden Power type."); + continue; + } + for (var stat in BattleStatNames) { + if ((curSet.ivs[stat] === undefined ? 31 : curSet.ivs[stat]) !== (Dex.types.get(hpType).HPivs[stat] || 31)) { + defaultIvs = false; + break; + } + } } + } + if (defaultIvs && !hpType) { for (var stat in BattleStatNames) { - if ((curSet.ivs[stat] === undefined ? 31 : curSet.ivs[stat]) !== (Dex.types.get(hpType).HPivs[stat] || 31)) { + if (curSet.ivs[stat] !== 31 && curSet.ivs[stat] !== undefined) { defaultIvs = false; break; } } } - } - if (defaultIvs && !hpType) { - for (var stat in BattleStatNames) { - if (curSet.ivs[stat] !== 31 && curSet.ivs[stat] !== undefined) { - defaultIvs = false; - break; + if (!defaultIvs) { + for (var stat in BattleStatNames) { + if (typeof curSet.ivs[stat] === 'undefined' || isNaN(curSet.ivs[stat]) || curSet.ivs[stat] == 31) continue; + if (first) { + text += 'IVs: '; + first = false; + } else { + text += ' / '; + } + text += '' + curSet.ivs[stat] + ' ' + BattleStatNames[stat]; } } } - if (!defaultIvs) { - for (var stat in BattleStatNames) { - if (typeof curSet.ivs[stat] === 'undefined' || isNaN(curSet.ivs[stat]) || curSet.ivs[stat] == 31) continue; - if (first) { - text += 'IVs: '; - first = false; - } else { - text += ' / '; - } - text += '' + curSet.ivs[stat] + ' ' + BattleStatNames[stat]; - } + if (!first) { + text += " \n"; } } - if (!first) { - text += " \n"; - } if (curSet.moves) for (var j = 0; j < curSet.moves.length; j++) { var move = curSet.moves[j]; if (move.substr(0, 13) === 'Hidden Power ') { @@ -1671,7 +1673,7 @@ Storage.nwSaveTeam = function (team) { this.nwDeleteTeam(team); } team.filename = filename; - fs.writeFile(this.dir + 'Teams/' + filename, Storage.exportTeam(team.team).replace(/\n/g, '\r\n'), function () {}); + fs.writeFile(this.dir + 'Teams/' + filename, Storage.exportTeam(team.team, team.gen).replace(/\n/g, '\r\n'), function () {}); }; Storage.nwSaveTeams = function () { @@ -1707,7 +1709,7 @@ Storage.nwDoSaveAllTeams = function () { filename = $.trim(filename).replace(/[\\\/]+/g, ''); team.filename = filename; - fs.writeFile(this.dir + 'Teams/' + filename, Storage.exportTeam(team.team).replace(/\n/g, '\r\n'), function () {}); + fs.writeFile(this.dir + 'Teams/' + filename, Storage.exportTeam(team.team, team.gen).replace(/\n/g, '\r\n'), function () {}); } }; From 3ee277318dd5164775ca53a45a388c7e545924d7 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Fri, 16 Dec 2022 11:51:24 -0600 Subject: [PATCH 368/770] Don't show "of Ruin" effects on inactive allies (#2058) --- src/battle-tooltips.ts | 8 ++++---- src/battle.ts | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 070e08529a..633ad9f6cb 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1208,16 +1208,16 @@ class BattleTooltips { if (ability === 'furcoat') { stats.def *= 2; } - if (this.battle.abilityActive('Vessel of Ruin', clientPokemon)) { + if (this.battle.abilityActive('Vessel of Ruin', pokemon)) { stats.spa = Math.floor(stats.spa * 0.75); } - if (this.battle.abilityActive('Sword of Ruin', clientPokemon)) { + if (this.battle.abilityActive('Sword of Ruin', pokemon)) { stats.def = Math.floor(stats.def * 0.75); } - if (this.battle.abilityActive('Tablets of Ruin', clientPokemon)) { + if (this.battle.abilityActive('Tablets of Ruin', pokemon)) { stats.atk = Math.floor(stats.atk * 0.75); } - if (this.battle.abilityActive('Beads of Ruin', clientPokemon)) { + if (this.battle.abilityActive('Beads of Ruin', pokemon)) { stats.spd = Math.floor(stats.spd * 0.75); } const sideConditions = this.battle.mySide.sideConditions; diff --git a/src/battle.ts b/src/battle.ts index 52aa639c42..ae299528ca 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1190,7 +1190,7 @@ export class Battle { } return false; } - abilityActive(abilities: string | string[], excludePokemon?: Pokemon | null) { + abilityActive(abilities: string | string[], excludePokemon?: Pokemon | ServerPokemon | null) { if (typeof abilities === 'string') abilities = [abilities]; if (this.ngasActive()) { abilities = abilities.filter(a => this.dex.abilities.get(a).isPermanent); @@ -1198,6 +1198,10 @@ export class Battle { } for (const active of this.getAllActive()) { if (active === excludePokemon) continue; + if (excludePokemon && this.pokemonControlled === 1 && + active.ident.slice(0, 2) === excludePokemon.ident.slice(0, 2)) { + continue; + } if (abilities.includes(active.ability) && !active.volatiles['gastroacid']) { return true; } From 95a51ce71a11f776b37486c22f44dc213c87f067 Mon Sep 17 00:00:00 2001 From: Mirko Spinato <30316462+harasuke@users.noreply.github.com> Date: Mon, 19 Dec 2022 23:33:44 +0100 Subject: [PATCH 369/770] Add CSS class based on field slot (#2043) --- src/battle-animations.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index e90ee6a6d8..fccac6ea4a 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -2653,8 +2653,19 @@ export class PokemonSprite extends Sprite { // Statbar ///////////////////////////////////////////////////////////////////// + getClassForPosition(slot: number) { + // DOUBLES: Slot0 -> left / Slot1 -> Right + // TRIPLES: slot0 -> left / Slot1 -> Center / Slot2 -> Right + const position = [ + ' leftstatbar', + this.scene.activeCount === 3 ? ' centerstatbar' : ' rightstatbar', + ' rightstatbar', + ]; + return position[slot]; + } + getStatbarHTML(pokemon: Pokemon) { - let buf = '

        `; } @@ -1429,8 +1436,8 @@ class BattleTooltips { moveType = 'Psychic'; } } - if (move.id === 'terablast' && pokemon.teraType) { - moveType = pokemon.teraType as TypeName; + if (move.id === 'terablast' && pokemon.terastallized) { + moveType = pokemon.terastallized as TypeName; } // Aura Wheel as Morpeko-Hangry changes the type to Dark @@ -2062,12 +2069,12 @@ class BattleTooltips { return value; } - getPokemonTypes(pokemon: Pokemon | ServerPokemon): ReadonlyArray { + getPokemonTypes(pokemon: Pokemon | ServerPokemon, preterastallized?: boolean): ReadonlyArray { if (!(pokemon as Pokemon).getTypes) { return this.battle.dex.species.get(pokemon.speciesForme).types; } - return (pokemon as Pokemon).getTypeList(); + return (pokemon as Pokemon).getTypeList(undefined, preterastallized); } pokemonHasType(pokemon: Pokemon | ServerPokemon, type: TypeName, types?: ReadonlyArray) { if (!types) types = this.getPokemonTypes(pokemon); diff --git a/src/battle.ts b/src/battle.ts index ae299528ca..ced509acdc 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -90,7 +90,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { itemEffect = ''; prevItem = ''; prevItemEffect = ''; - teraType = ''; + terastallized: string | '' = ''; boosts: {[stat: string]: number} = {}; status: StatusName | 'tox' | '' | '???' = ''; @@ -467,7 +467,6 @@ export class Pokemon implements PokemonDetails, PokemonHealth { } delete this.volatiles['transform']; delete this.volatiles['formechange']; - delete this.volatiles['terastallize']; pokemon.boosts = {}; pokemon.volatiles = {}; @@ -483,9 +482,11 @@ export class Pokemon implements PokemonDetails, PokemonHealth { this.removeVolatile('typeadd' as ID); } } - getTypes(serverPokemon?: ServerPokemon): [ReadonlyArray, TypeName | ''] { + getTypes(serverPokemon?: ServerPokemon, preterastallized?: boolean): [ReadonlyArray, TypeName | ''] { let types: ReadonlyArray; - if (this.volatiles.typechange) { + if (this.terastallized && !preterastallized) { + types = [this.terastallized as TypeName]; + } else if (this.volatiles.typechange) { types = this.volatiles.typechange[1].split('/'); } else { types = this.getSpecies(serverPokemon).types; @@ -537,8 +538,8 @@ export class Pokemon implements PokemonDetails, PokemonHealth { } return ability.name; } - getTypeList(serverPokemon?: ServerPokemon) { - const [types, addedType] = this.getTypes(serverPokemon); + getTypeList(serverPokemon?: ServerPokemon, preterastallized?: boolean) { + const [types, addedType] = this.getTypes(serverPokemon, preterastallized); return addedType ? types.concat(addedType) : types; } getSpeciesForme(serverPokemon?: ServerPokemon): string { @@ -941,6 +942,7 @@ export class Side { pokemon.fainted = true; pokemon.hp = 0; + pokemon.terastallized = ''; if (pokemon.side.faintCounter < 100) pokemon.side.faintCounter++; this.battle.scene.animFaint(pokemon); @@ -994,6 +996,10 @@ export interface ServerPokemon extends PokemonDetails, PokemonHealth { pokeball: string; /** false if the pokemon cannot gigantamax, otherwise a string containing the full name of its G-max move */ gigantamax: string | false; + /** always the Tera Type of the Pokemon, regardless of whether it is terastallized or not */ + teraType: string; + /** falsy if the pokemon is not terastallized, otherwise it is the Tera Type of the Pokemon */ + terastallized: string; } export class Battle { @@ -2469,7 +2475,7 @@ export class Battle { case '-terastallize': { let poke = this.getPokemon(args[1])!; let type = Dex.types.get(args[2]).name; - poke.teraType = type; + poke.terastallized = type; this.scene.animTransform(poke, true, true); this.log(args, kwArgs); break; @@ -2484,6 +2490,7 @@ export class Battle { this.activateAbility(ofpoke || poke, fromeffect); switch (effect.id) { case 'typechange': + if (poke.terastallized) break; if (ofpoke && fromeffect.id === 'reflecttype') { poke.copyTypesFrom(ofpoke); } else { @@ -2632,7 +2639,9 @@ export class Battle { this.scene.resultAnim(poke, 'Reflect', 'good'); break; } - poke.addVolatile(effect.id); + if (!(effect.id === 'typechange' && poke.terastallized)) { + poke.addVolatile(effect.id); + } this.scene.updateStatbar(poke); this.log(args, kwArgs); break; From 0f29a6f922fb5c46f3f34f05f4a97b07ccfe23f9 Mon Sep 17 00:00:00 2001 From: Alexander B <4866817+MathyFurret@users.noreply.github.com> Date: Thu, 22 Dec 2022 15:24:35 -0600 Subject: [PATCH 371/770] Don't show revived active Pokemon immediately (#2061) --- src/battle.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index ced509acdc..919a17c281 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1743,10 +1743,6 @@ export class Battle { poke.fainted = false; poke.status = ''; this.scene.updateSidebar(side); - // Revived while still on the field - if (!side.active[poke.slot]) { - poke.side.replace(poke); - } break; } } From a4eef221bd748e7365d560ecb289eeb3b7d3f7e1 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Thu, 22 Dec 2022 15:25:00 -0600 Subject: [PATCH 372/770] Update to handle esbuild migration (#2064) --- build-tools/build-indexes | 20 ++++++++++---------- build-tools/build-learnsets | 2 +- build-tools/build-minidex | 2 +- test/check-filenames | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index e8518a9ac5..2e6a89dc4d 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -19,7 +19,7 @@ child_process.execSync('git pull', {cwd: 'data/pokemon-showdown'}); child_process.execSync('npm run build', {cwd: 'data/pokemon-showdown'}); console.log("DONE"); -const Dex = require('../data/pokemon-showdown/.sim-dist/dex').Dex; +const Dex = require('../data/pokemon-showdown/dist/sim/dex').Dex; const toID = Dex.toID; process.stdout.write("Loading gen 6 data... "); Dex.includeData(); @@ -1075,7 +1075,7 @@ console.log("DONE"); process.stdout.write("Building `data/pokedex.js`... "); { - const Pokedex = requireNoCache('../data/pokemon-showdown/.data-dist/pokedex.js').Pokedex; + const Pokedex = requireNoCache('../data/pokemon-showdown/dist/data/pokedex.js').Pokedex; for (const id in Pokedex) { const entry = Pokedex[id]; if (Dex.data.FormatsData[id]) { @@ -1100,7 +1100,7 @@ console.log("DONE"); process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.js`..."); { - const Moves = requireNoCache('../data/pokemon-showdown/.data-dist/moves.js').Moves; + const Moves = requireNoCache('../data/pokemon-showdown/dist/data/moves.js').Moves; for (const id in Moves) { const move = Dex.moves.get(Moves[id].name); if (move.desc) Moves[id].desc = move.desc; @@ -1116,7 +1116,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j *********************************************************/ { - const Items = requireNoCache('../data/pokemon-showdown/.data-dist/items.js').Items; + const Items = requireNoCache('../data/pokemon-showdown/dist/data/items.js').Items; for (const id in Items) { const item = Dex.items.get(Items[id].name); if (item.desc) Items[id].desc = item.desc; @@ -1131,7 +1131,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j *********************************************************/ { - const Abilities = requireNoCache('../data/pokemon-showdown/.data-dist/abilities.js').Abilities; + const Abilities = requireNoCache('../data/pokemon-showdown/dist/data/abilities.js').Abilities; for (const id in Abilities) { const ability = Dex.abilities.get(Abilities[id].name); if (ability.desc) Abilities[id].desc = ability.desc; @@ -1146,7 +1146,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j *********************************************************/ { - const TypeChart = requireNoCache('../data/pokemon-showdown/.data-dist/typechart.js').TypeChart; + const TypeChart = requireNoCache('../data/pokemon-showdown/dist/data/typechart.js').TypeChart; const buf = 'exports.BattleTypeChart = ' + es3stringify(TypeChart) + ';'; fs.writeFileSync('data/typechart.js', buf); } @@ -1156,7 +1156,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j *********************************************************/ { - const Aliases = requireNoCache('../data/pokemon-showdown/.data-dist/aliases.js').Aliases; + const Aliases = requireNoCache('../data/pokemon-showdown/dist/data/aliases.js').Aliases; const buf = 'exports.BattleAliases = ' + es3stringify(Aliases) + ';'; fs.writeFileSync('data/aliases.js', buf); } @@ -1166,7 +1166,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j *********************************************************/ { - const FormatsData = requireNoCache('../data/pokemon-showdown/.data-dist/formats-data.js').FormatsData; + const FormatsData = requireNoCache('../data/pokemon-showdown/dist/data/formats-data.js').FormatsData; const buf = 'exports.BattleFormatsData = ' + es3stringify(FormatsData) + ';'; fs.writeFileSync('data/formats-data.js', buf); } @@ -1176,7 +1176,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j *********************************************************/ { - const Formats = requireNoCache('../data/pokemon-showdown/.config-dist/formats.js').Formats; + const Formats = requireNoCache('../data/pokemon-showdown/dist/config/formats.js').Formats; const buf = 'exports.Formats = ' + es3stringify(Formats) + ';'; fs.writeFileSync('data/formats.js', buf); } @@ -1186,7 +1186,7 @@ process.stdout.write("Building `data/moves,items,abilities,typechart,learnsets.j *********************************************************/ { - const Learnsets = requireNoCache('../data/pokemon-showdown/.data-dist/learnsets.js').Learnsets; + const Learnsets = requireNoCache('../data/pokemon-showdown/dist/data/learnsets.js').Learnsets; const buf = 'exports.BattleLearnsets = ' + es3stringify(Learnsets) + ';'; fs.writeFileSync('data/learnsets.js', buf); fs.writeFileSync('data/learnsets.json', JSON.stringify(Learnsets)); diff --git a/build-tools/build-learnsets b/build-tools/build-learnsets index eca10c0e2d..c027257b77 100755 --- a/build-tools/build-learnsets +++ b/build-tools/build-learnsets @@ -18,7 +18,7 @@ const thisFile = __filename; const thisDir = __dirname; const rootDir = path.resolve(thisDir, '..'); -const Dex = require('../data/pokemon-showdown/.sim-dist/dex').Dex; +const Dex = require('../data/pokemon-showdown/dist/sim/dex').Dex; const toID = Dex.toID; function updateLearnsets(callback) { diff --git a/build-tools/build-minidex b/build-tools/build-minidex index 7d797ddd6c..890b75d353 100755 --- a/build-tools/build-minidex +++ b/build-tools/build-minidex @@ -6,7 +6,7 @@ const path = require("path"); process.chdir(path.resolve(__dirname, '..')); const imageSize = require('image-size'); -const Dex = require('./../data/pokemon-showdown/.sim-dist/dex').Dex; +const Dex = require('./../data/pokemon-showdown/dist/sim/dex').Dex; const toID = Dex.toID; process.stdout.write("Updating animated sprite dimensions... "); diff --git a/test/check-filenames b/test/check-filenames index db99879220..08be1ff82f 100755 --- a/test/check-filenames +++ b/test/check-filenames @@ -2,7 +2,7 @@ const fs = require('fs'); const path = require('path'); -const Dex = require('../data/pokemon-showdown/.sim-dist/dex').Dex; +const Dex = require('../data/pokemon-showdown/dist/sim/dex').Dex; const dir = path.resolve(process.argv[2]); const ext = process.argv[3]; From a8a630fc12f549a3faa13282be4428d443701e4c Mon Sep 17 00:00:00 2001 From: Hisuian Zoroark <96159984+HisuianZoroark@users.noreply.github.com> Date: Thu, 22 Dec 2022 19:55:45 -0500 Subject: [PATCH 373/770] Battle turn counters: Support Persistent extensions (#1982) --- src/battle.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index 919a17c281..6ddf4df7bc 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -678,7 +678,7 @@ export class Side { if (this.foe && this.avatar === this.foe.avatar) this.rollTrainerSprites(); } } - addSideCondition(effect: Effect) { + addSideCondition(effect: Effect, persist: boolean) { let condition = effect.id; if (this.sideConditions[condition]) { if (condition === 'spikes' || condition === 'toxicspikes') { @@ -696,7 +696,7 @@ export class Side { this.sideConditions[condition] = [effect.name, 1, 5, this.battle.gen >= 4 ? 8 : 0]; break; case 'safeguard': - this.sideConditions[condition] = [effect.name, 1, 5, 0]; + this.sideConditions[condition] = [effect.name, 1, persist ? 7 : 5, 0]; break; case 'lightscreen': this.sideConditions[condition] = [effect.name, 1, 5, this.battle.gen >= 4 ? 8 : 0]; @@ -705,7 +705,7 @@ export class Side { this.sideConditions[condition] = [effect.name, 1, 5, 0]; break; case 'tailwind': - this.sideConditions[condition] = [effect.name, 1, this.battle.gen >= 5 ? 4 : 3, 0]; + this.sideConditions[condition] = [effect.name, 1, this.battle.gen >= 5 ? persist ? 6 : 4 : persist ? 5 : 3, 0]; break; case 'luckychant': this.sideConditions[condition] = [effect.name, 1, 5, 0]; @@ -2945,7 +2945,7 @@ export class Battle { case '-sidestart': { let side = this.getSide(args[1]); let effect = Dex.getEffect(args[2]); - side.addSideCondition(effect); + side.addSideCondition(effect, !!kwArgs.persistent); switch (effect.id) { case 'tailwind': @@ -2998,6 +2998,7 @@ export class Battle { let poke = this.getPokemon(kwArgs.of); let fromeffect = Dex.getEffect(kwArgs.from); this.activateAbility(poke, fromeffect); + let minTimeLeft = 5; let maxTimeLeft = 0; if (effect.id.endsWith('terrain')) { for (let i = this.pseudoWeather.length - 1; i >= 0; i--) { @@ -3009,7 +3010,8 @@ export class Battle { } if (this.gen > 6) maxTimeLeft = 8; } - this.addPseudoWeather(effect.name, 5, maxTimeLeft); + if (kwArgs.persistent) minTimeLeft += 2; + this.addPseudoWeather(effect.name, minTimeLeft, maxTimeLeft); switch (effect.id) { case 'gravity': From c3bd856af85948b2525893bdb94ac463adf857a1 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Thu, 22 Dec 2022 18:56:38 -0600 Subject: [PATCH 374/770] Don't try to minimize Koraidon's Atk IV (#2060) --- js/client-teambuilder.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index a389c98b21..fd6e43c572 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -3192,7 +3192,8 @@ if (this.curTeam.format === 'gen7hiddentype') return; var minAtk = true; - if (set.ability === 'Battle Bond') minAtk = false; // only available through an event with 31 Atk IVs + // only available through an event with 31 Atk IVs + if (set.ability === 'Battle Bond' || ['Koraidon', 'Miraidon'].includes(set.species)) minAtk = false; var hpModulo = (this.curTeam.gen >= 6 ? 2 : 4); var hasHiddenPower = false; var moves = set.moves; From 795d5aedc82549beeef792194620ca2c2c441699 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Thu, 22 Dec 2022 18:57:00 -0600 Subject: [PATCH 375/770] Tooltips: Calculate Speed correctly for CGT (#2062) --- src/battle-tooltips.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 7c7e07bc75..f037015400 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1349,8 +1349,9 @@ class BattleTooltips { let level = pokemon.volatiles.transform?.[4] || pokemon.level; let tier = this.battle.tier; let gen = this.battle.gen; + let isCGT = tier.includes('Computer-Generated Teams'); let isRandomBattle = tier.includes('Random Battle') || - (tier.includes('Random') && tier.includes('Battle') && gen >= 6); + (tier.includes('Random') && tier.includes('Battle') && gen >= 6) || isCGT; let minNature = (isRandomBattle || gen < 3) ? 1 : 0.9; let maxNature = (isRandomBattle || gen < 3) ? 1 : 1.1; @@ -1365,8 +1366,8 @@ class BattleTooltips { else if (tier.includes('Random')) max += 20; } else { let maxIvEvOffset = maxIv + ((isRandomBattle && gen >= 3) ? 21 : 63); - min = tr(tr(2 * baseSpe * level / 100 + 5) * minNature); max = tr(tr((2 * baseSpe + maxIvEvOffset) * level / 100 + 5) * maxNature); + min = isCGT ? max : tr(tr(2 * baseSpe * level / 100 + 5) * minNature); } return [min, max]; } From b5fa39bbb97999bb3cb591d8387bfd1189dbdd69 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 22 Dec 2022 19:57:28 -0500 Subject: [PATCH 376/770] Fix Transform not copying pre-Terastallized types (#2063) --- src/battle-tooltips.ts | 2 +- src/battle.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index f037015400..47303c29dc 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -2070,7 +2070,7 @@ class BattleTooltips { return value; } - getPokemonTypes(pokemon: Pokemon | ServerPokemon, preterastallized?: boolean): ReadonlyArray { + getPokemonTypes(pokemon: Pokemon | ServerPokemon, preterastallized = false): ReadonlyArray { if (!(pokemon as Pokemon).getTypes) { return this.battle.dex.species.get(pokemon.speciesForme).types; } diff --git a/src/battle.ts b/src/battle.ts index 6ddf4df7bc..ca93ca3c35 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -473,8 +473,8 @@ export class Pokemon implements PokemonDetails, PokemonHealth { pokemon.side.battle.scene.removeTransform(pokemon); pokemon.statusStage = 0; } - copyTypesFrom(pokemon: Pokemon) { - const [types, addedType] = pokemon.getTypes(); + copyTypesFrom(pokemon: Pokemon, preterastallized = false) { + const [types, addedType] = pokemon.getTypes(undefined, preterastallized); this.addVolatile('typechange' as ID, types.join('/')); if (addedType) { this.addVolatile('typeadd' as ID, addedType); @@ -482,7 +482,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { this.removeVolatile('typeadd' as ID); } } - getTypes(serverPokemon?: ServerPokemon, preterastallized?: boolean): [ReadonlyArray, TypeName | ''] { + getTypes(serverPokemon?: ServerPokemon, preterastallized = false): [ReadonlyArray, TypeName | ''] { let types: ReadonlyArray; if (this.terastallized && !preterastallized) { types = [this.terastallized as TypeName]; @@ -538,7 +538,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { } return ability.name; } - getTypeList(serverPokemon?: ServerPokemon, preterastallized?: boolean) { + getTypeList(serverPokemon?: ServerPokemon, preterastallized = false) { const [types, addedType] = this.getTypes(serverPokemon, preterastallized); return addedType ? types.concat(addedType) : types; } @@ -2417,7 +2417,7 @@ export class Battle { } poke.boosts = {...tpoke.boosts}; - poke.copyTypesFrom(tpoke); + poke.copyTypesFrom(tpoke, true); poke.ability = tpoke.ability; poke.timesAttacked = tpoke.timesAttacked; const targetForme = tpoke.volatiles.formechange; From 26b69e339ac673fc3a91e65338e080d170d0b717 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Thu, 22 Dec 2022 19:29:30 -0600 Subject: [PATCH 377/770] Remember Ability Shield after it activates (#2065) --- src/battle.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/battle.ts b/src/battle.ts index ca93ca3c35..2bf823565a 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2934,6 +2934,9 @@ export class Battle { case 'quickclaw': poke.item = 'Quick Claw'; break; + case 'abilityshield': + poke.item = 'Ability Shield'; + break; default: if (kwArgs.broken) { // for custom moves that break protection this.scene.resultAnim(poke, 'Protection broken', 'bad'); From 37e88a16ead5d2a6f78fb09d494bdf23f909f4a9 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Tue, 27 Dec 2022 13:37:45 -0500 Subject: [PATCH 378/770] Fix Costar not having a proper activation animation (#2066) --- src/battle.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/battle.ts b/src/battle.ts index 2bf823565a..c488b2a93f 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1880,6 +1880,10 @@ export class Battle { case '-copyboost': { let poke = this.getPokemon(args[1])!; let frompoke = this.getPokemon(args[2])!; + if (!kwArgs.silent && kwArgs.from) { + let effect = Dex.getEffect(kwArgs.from); + this.activateAbility(poke, effect); + } let stats = args[3] ? args[3].split(', ') : ['atk', 'def', 'spa', 'spd', 'spe', 'accuracy', 'evasion']; for (const stat of stats) { poke.boosts[stat] = frompoke.boosts[stat]; From e38eb07bc553863b4d7a8baaf78dc46fcb4abc23 Mon Sep 17 00:00:00 2001 From: Alexander B <4866817+MathyFurret@users.noreply.github.com> Date: Tue, 27 Dec 2022 12:40:47 -0600 Subject: [PATCH 379/770] Support Terastallization in switch details (#2067) --- src/battle.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/battle.ts b/src/battle.ts index c488b2a93f..ff9bee2501 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2476,6 +2476,8 @@ export class Battle { let poke = this.getPokemon(args[1])!; let type = Dex.types.get(args[2]).name; poke.terastallized = type; + poke.details += `, tera:${type}`; + poke.searchid += `, tera:${type}`; this.scene.animTransform(poke, true, true); this.log(args, kwArgs); break; From da31738659af14938703901af57e00c14e88cd55 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Tue, 27 Dec 2022 13:41:29 -0500 Subject: [PATCH 380/770] Prefer [from] effect for -start template (#2068) --- src/battle-text-parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 353001fa83..a62603afe6 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -602,7 +602,7 @@ class BattleTextParser { if (templateId === 'start' && kwArgs.from?.startsWith('item:')) { templateId += 'FromItem'; } - const template = this.template(templateId, effect); + const template = this.template(templateId, kwArgs.from, effect); return line1 + template.replace('[POKEMON]', this.pokemon(pokemon)).replace('[EFFECT]', this.effect(effect)).replace('[MOVE]', arg3).replace('[SOURCE]', this.pokemon(kwArgs.of)).replace('[ITEM]', this.effect(kwArgs.from)); } From b13c25eea7a5f0112111927703467eea56534a3d Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 1 Jan 2023 20:55:05 -0500 Subject: [PATCH 381/770] Tooltips: Show BP boost for Origin items & Vile Vial (#2069) --- src/battle-tooltips.ts | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 47303c29dc..0601cf4148 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1996,18 +1996,23 @@ class BattleTooltips { 'Spell Tag': 'Ghost', 'Twisted Spoon': 'Psychic', }; - static orbUsers: {[speciesForme: string]: string} = { - 'Latias': 'Soul Dew', - 'Latios': 'Soul Dew', - 'Dialga': 'Adamant Orb', - 'Palkia': 'Lustrous Orb', - 'Giratina': 'Griseous Orb', + static orbUsers: {[speciesForme: string]: string[]} = { + 'Latias': ['Soul Dew'], + 'Latios': ['Soul Dew'], + 'Dialga': ['Adamant Crystal', 'Adamant Orb'], + 'Palkia': ['Lustrous Globe', 'Lustrous Orb'], + 'Giratina': ['Griseous Core', 'Griseous Orb'], + 'Venomicon': ['Vile Vial'], }; - static orbTypes: {[itemName: string]: TypeName} = { - 'Soul Dew': 'Psychic', - 'Adamant Orb': 'Steel', - 'Lustrous Orb': 'Water', - 'Griseous Orb': 'Ghost', + static orbTypes: {[itemName: string]: TypeName[]} = { + 'Soul Dew': ['Psychic', 'Dragon'], + 'Adamant Crystal': ['Steel', 'Dragon'], + 'Adamant Orb': ['Steel', 'Dragon'], + 'Lustrous Globe': ['Water', 'Dragon'], + 'Lustrous Orb': ['Water', 'Dragon'], + 'Griseous Core': ['Ghost', 'Dragon'], + 'Griseous Orb': ['Ghost', 'Dragon'], + 'Vile Vial': ['Poison', 'Flying'], }; static noGemMoves = [ 'Fire Pledge', @@ -2051,8 +2056,8 @@ class BattleTooltips { // Pokemon-specific items if (item.name === 'Soul Dew' && this.battle.gen < 7) return value; - if (BattleTooltips.orbUsers[speciesName] === item.name && - [BattleTooltips.orbTypes[item.name], 'Dragon'].includes(moveType)) { + if (BattleTooltips.orbUsers[speciesName]?.includes(item.name) && + BattleTooltips.orbTypes[item.name]?.includes(moveType)) { value.itemModify(1.2); return value; } From d9e527781b062a90a88e1c850de942644291f720 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 1 Jan 2023 20:55:54 -0500 Subject: [PATCH 382/770] Tooltips: Fix Tera Blast interaction with -ate abilities (#2070) --- src/battle-tooltips.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 0601cf4148..8612218c2d 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1464,7 +1464,8 @@ class BattleTooltips { const noTypeOverride = [ 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'struggle', 'technoblast', 'terablast', 'terrainpulse', 'weatherball', ]; - if (!noTypeOverride.includes(move.id)) { + const allowTypeOverride = !noTypeOverride.includes(move.id) && (move.id !== 'terablast' || !pokemon.terastallized); + if (allowTypeOverride) { if (this.battle.rules['Revelationmons Mod']) { const [types] = pokemon.getTypes(serverPokemon); for (let i = 0; i < types.length; i++) { @@ -1862,10 +1863,11 @@ class BattleTooltips { } } const noTypeOverride = [ - 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'struggle', 'technoblast', 'terablast', 'terrainpulse', 'weatherball', + 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'struggle', 'technoblast', 'terrainpulse', 'weatherball', ]; + const allowTypeOverride = !noTypeOverride.includes(move.id) && (move.id !== 'terablast' || !pokemon.terastallized); if ( - move.category !== 'Status' && !noTypeOverride.includes(move.id) && !move.isZ && !move.isMax && + move.category !== 'Status' && allowTypeOverride && !move.isZ && !move.isMax && !move.id.startsWith('hiddenpower') ) { if (move.type === 'Normal') { From 9b5baaf4f221bc5906502e7c243e8c0b42a3d662 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 1 Jan 2023 20:56:35 -0500 Subject: [PATCH 383/770] Add formatted volatile tag for Glaive Rush (#2071) --- src/battle-animations.ts | 1 + src/battle.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 10abd56f47..84bef74f50 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -1832,6 +1832,7 @@ export class PokemonSprite extends Sprite { shelltrap: ['Trap set', 'neutral'], powder: ['Powder', 'bad'], electrify: ['Electrify', 'bad'], + glaiverush: ['Glaive Rush', 'bad'], ragepowder: ['Rage Powder', 'good'], followme: ['Follow Me', 'good'], instruct: ['Instruct', 'neutral'], diff --git a/src/battle.ts b/src/battle.ts index ff9bee2501..12d4c2ed92 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2804,7 +2804,6 @@ export class Battle { let poke = this.getPokemon(args[1])!; let effect = Dex.getEffect(args[2]); poke.addMovestatus(effect.id); - switch (effect.id) { case 'grudge': this.scene.resultAnim(poke, 'Grudge', 'neutral'); @@ -2813,6 +2812,7 @@ export class Battle { this.scene.resultAnim(poke, 'Destiny Bond', 'neutral'); break; } + this.scene.updateStatbar(poke); this.log(args, kwArgs); break; } From 2dbf16a85966dfe24a931b777a90ef8834d08bac Mon Sep 17 00:00:00 2001 From: Annika Date: Mon, 2 Jan 2023 00:24:40 -0500 Subject: [PATCH 384/770] Update credits --- website/credits.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/credits.php b/website/credits.php index 15e75e2a38..bb9efc88d5 100644 --- a/website/credits.php +++ b/website/credits.php @@ -67,13 +67,14 @@
      • Catherine D. [SailorCosmos, Matryoshkat] – Art (battle animations)

      • Cody Thompson [Rising_Dusk] – Development

      • [Enigami] – Development

      • +
      • [Hisuian Zoroark] – Development (Staff Bros format)

      • [Honko] – Development (damage calculator)

      • Ian Clail [Layell] – Art (battle graphics, sprites)

      • -
      • [Instruct] – Development (Staff Bros format)

      • Jacob McLemore – Development

      • Erik Bruce [Kalalokki] – Art (minisprite resizing)

      • Jeremy Piemonte [panpawn] – Development

      • [leparagon] – Art (sprites, minisprite resizing)

      • +
      • [livid washed] – Development

      • Luke Harmon-Vellotti [moo, CheeseMuffin] – Development

      • Parth Mane [PartMan] – Development

      • [Plague von Karma] – Development (Gen 1), Research

      • From 6142a35b391f5dba268b8a1a4c763f2a875e499e Mon Sep 17 00:00:00 2001 From: Leonard Craft III Date: Mon, 2 Jan 2023 00:09:00 -0600 Subject: [PATCH 385/770] Add Karthik to credits (#2076) --- website/credits.php | 1 + 1 file changed, 1 insertion(+) diff --git a/website/credits.php b/website/credits.php index bb9efc88d5..99233d80ab 100644 --- a/website/credits.php +++ b/website/credits.php @@ -73,6 +73,7 @@
      • Jacob McLemore – Development

      • Erik Bruce [Kalalokki] – Art (minisprite resizing)

      • Jeremy Piemonte [panpawn] – Development

      • +
      • Karthik Bandagonda – Development

      • [leparagon] – Art (sprites, minisprite resizing)

      • [livid washed] – Development

      • Luke Harmon-Vellotti [moo, CheeseMuffin] – Development

      • From 84d97c58ea6c3a05f8db4c624d9342f50204c319 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Fri, 6 Jan 2023 23:23:30 -0700 Subject: [PATCH 386/770] Teambuilder: Update move viability for Gen 9 (#2077) --- src/battle-dex-search.ts | 61 +++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index b9f05f3ad4..fdceb92618 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1224,9 +1224,12 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { } return results; } - private moveIsNotUseless(id: ID, species: Species, abilityid: ID, itemid: ID, moves: string[]) { + private moveIsNotUseless(id: ID, species: Species, moves: string[], set: PokemonSet | null) { const dex = this.dex; + let abilityid: ID = set ? toID(set.ability) : '' as ID; + const itemid: ID = set ? toID(set.item) : '' as ID; + if (dex.gen === 1) { // Usually not useless for Gen 1 if ([ @@ -1284,7 +1287,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { case 'fakeout': case 'flamecharge': case 'nuzzle': case 'poweruppunch': return abilityid !== 'sheerforce'; case 'solarbeam': case 'solarblade': - return ['desolateland', 'drought', 'chlorophyll'].includes(abilityid) || itemid === 'powerherb'; + return ['desolateland', 'drought', 'chlorophyll', 'orichalcumpulse'].includes(abilityid) || itemid === 'powerherb'; case 'dynamicpunch': case 'grasswhistle': case 'inferno': case 'sing': case 'zapcannon': return abilityid === 'noguard'; case 'heatcrash': case 'heavyslam': @@ -1294,19 +1297,23 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return ['technician', 'toughclaws'].includes(abilityid) && !moves.includes('bravebird'); case 'ancientpower': return ['serenegrace', 'technician'].includes(abilityid) || !moves.includes('powergem'); + case 'aquajet': + return !moves.includes('jetpunch'); case 'aurawheel': return species.baseSpecies === 'Morpeko'; + case 'axekick': + return !moves.includes('highjumpkick'); case 'bellydrum': - return moves.includes('aquajet') || moves.includes('extremespeed') || + return moves.includes('aquajet') || moves.includes('jetpunch') || moves.includes('extremespeed') || ['iceface', 'unburden'].includes(abilityid); case 'bulletseed': return ['skilllink', 'technician'].includes(abilityid); + case 'chillingwater': + return !moves.includes('scald'); case 'counter': return species.baseStats.hp >= 65; case 'darkvoid': return dex.gen < 7; - case 'drainingkiss': - return abilityid === 'triage'; case 'dualwingbeat': return abilityid === 'technician' || !moves.includes('drillpeck'); case 'feint': @@ -1317,16 +1324,20 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return species.baseStats.spe <= 60; case 'headbutt': return abilityid === 'serenegrace'; + case 'hex': + return !moves.includes('infernalparade'); case 'hiddenpowerelectric': return (dex.gen < 4 && !moves.includes('thunderpunch')) && !moves.includes('thunderbolt'); case 'hiddenpowerfighting': return (dex.gen < 4 && !moves.includes('brickbreak')) && !moves.includes('aurasphere') && !moves.includes('focusblast'); case 'hiddenpowerfire': - return (dex.gen < 4 && !moves.includes('firepunch')) && !moves.includes('flamethrower'); + return (dex.gen < 4 && !moves.includes('firepunch')) && !moves.includes('flamethrower') && + !moves.includes('mysticalfire') && !moves.includes('burningjealousy'); case 'hiddenpowergrass': return !moves.includes('energyball') && !moves.includes('grassknot') && !moves.includes('gigadrain'); case 'hiddenpowerice': - return !moves.includes('icebeam') && (dex.gen < 4 && !moves.includes('icepunch')) || (dex.gen > 5 && !moves.includes('aurorabeam')); + return !moves.includes('icebeam') && (dex.gen < 4 && !moves.includes('icepunch')) || + (dex.gen > 5 && !moves.includes('aurorabeam') && !moves.includes('glaciate')); case 'hiddenpowerflying': return dex.gen < 4 && !moves.includes('drillpeck'); case 'hiddenpowerbug': @@ -1337,6 +1348,10 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return species.id === 'hoopaunbound'; case 'hypnosis': return (dex.gen < 4 && !moves.includes('sleeppowder')) || (dex.gen > 6 && abilityid === 'baddreams'); + case 'icepunch': + return !moves.includes('icespinner') || ['sheerforce', 'ironfist'].includes(abilityid) || itemid === 'punchingglove'; + case 'iciclecrash': + return !moves.includes('mountaingale'); case 'icywind': // Keldeo needs Hidden Power for Electric/Ghost return species.baseSpecies === 'Keldeo' || this.formatType === 'doubles'; @@ -1347,7 +1362,9 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { case 'irontail': return dex.gen > 5 && !moves.includes('ironhead') && !moves.includes('gunkshot') && !moves.includes('poisonjab'); case 'jumpkick': - return !moves.includes('highjumpkick'); + return !moves.includes('highjumpkick') && !moves.includes('axekick'); + case 'lastresort': + return set && set.moves.length < 3; case 'leechlife': return dex.gen > 6; case 'mysticalfire': @@ -1356,6 +1373,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return dex.gen === 5; case 'nightslash': return !moves.includes('crunch') && !(moves.includes('knockoff') && dex.gen >= 6); + case 'outrage': + return !moves.includes('glaiverush'); case 'petaldance': return abilityid === 'owntempo'; case 'phantomforce': @@ -1367,13 +1386,15 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { case 'refresh': return !moves.includes('aromatherapy') && !moves.includes('healbell'); case 'risingvoltage': - return abilityid === 'electricsurge'; + return abilityid === 'electricsurge' || abilityid === 'hadronengine'; case 'rocktomb': return abilityid === 'technician'; case 'selfdestruct': return dex.gen < 5 && !moves.includes('explosion'); case 'shadowpunch': - return abilityid === 'ironfist'; + return abilityid === 'ironfist' && !moves.includes('ragefist'); + case 'shelter': + return !moves.includes('acidarmor') && !moves.includes('irondefense'); case 'smackdown': return species.types.includes('Ground'); case 'smartstrike': @@ -1392,6 +1413,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return dex.gen > 7; case 'terrainpulse': case 'waterpulse': return ['megalauncher', 'technician'].includes(abilityid) && !moves.includes('originpulse'); + case 'toxicspikes': + return abilityid !== 'toxicdebris'; case 'trickroom': return species.baseStats.spe <= 100; } @@ -1416,19 +1439,22 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { if (moveData.flags?.recharge) { return false; } + if (moveData.flags?.slicing) { + return abilityid === 'sharpness'; + } return !BattleMoveSearch.BAD_STRONG_MOVES.includes(id); } static readonly GOOD_STATUS_MOVES = [ - 'acidarmor', 'agility', 'aromatherapy', 'auroraveil', 'autotomize', 'banefulbunker', 'batonpass', 'bellydrum', 'bulkup', 'calmmind', 'clangoroussoul', 'coil', 'cottonguard', 'courtchange', 'curse', 'defog', 'destinybond', 'detect', 'disable', 'dragondance', 'drainingkiss', 'encore', 'extremeevoboost', 'geomancy', 'glare', 'haze', 'healbell', 'healingwish', 'healorder', 'heartswap', 'honeclaws', 'kingsshield', 'leechseed', 'lightscreen', 'lovelykiss', 'lunardance', 'magiccoat', 'maxguard', 'memento', 'milkdrink', 'moonlight', 'morningsun', 'nastyplot', 'naturesmadness', 'noretreat', 'obstruct', 'painsplit', 'partingshot', 'perishsong', 'protect', 'quiverdance', 'recover', 'reflect', 'reflecttype', 'rest', 'roar', 'rockpolish', 'roost', 'shellsmash', 'shiftgear', 'shoreup', 'slackoff', 'sleeppowder', 'sleeptalk', 'softboiled', 'spikes', 'spikyshield', 'spore', 'stealthrock', 'stickyweb', 'strengthsap', 'substitute', 'switcheroo', 'swordsdance', 'synthesis', 'tailglow', 'tailwind', 'taunt', 'thunderwave', 'toxic', 'toxicspikes', 'transform', 'trick', 'whirlwind', 'willowisp', 'wish', 'yawn', + 'acidarmor', 'agility', 'aromatherapy', 'auroraveil', 'autotomize', 'banefulbunker', 'batonpass', 'bellydrum', 'bulkup', 'calmmind', 'chillyreception', 'clangoroussoul', 'coil', 'cottonguard', 'courtchange', 'curse', 'defog', 'destinybond', 'detect', 'disable', 'dragondance', 'encore', 'extremeevoboost', 'filletaway', 'geomancy', 'glare', 'haze', 'healbell', 'healingwish', 'healorder', 'heartswap', 'honeclaws', 'kingsshield', 'leechseed', 'lightscreen', 'lovelykiss', 'lunardance', 'magiccoat', 'maxguard', 'memento', 'milkdrink', 'moonlight', 'morningsun', 'nastyplot', 'naturesmadness', 'noretreat', 'obstruct', 'painsplit', 'partingshot', 'perishsong', 'protect', 'quiverdance', 'recover', 'reflect', 'reflecttype', 'rest', 'revivalblessing', 'roar', 'rockpolish', 'roost', 'shedtail', 'shellsmash', 'shiftgear', 'shoreup', 'silktrap', 'slackoff', 'sleeppowder', 'sleeptalk', 'softboiled', 'spikes', 'spikyshield', 'spore', 'stealthrock', 'stickyweb', 'strengthsap', 'substitute', 'switcheroo', 'swordsdance', 'synthesis', 'tailglow', 'tailwind', 'taunt', 'thunderwave', 'tidyup', 'toxic', 'transform', 'trick', 'victorydance', 'whirlwind', 'willowisp', 'wish', 'yawn', ] as ID[] as readonly ID[]; static readonly GOOD_WEAK_MOVES = [ - 'accelerock', 'acrobatics', 'aquajet', 'avalanche', 'bonemerang', 'bouncybubble', 'bulletpunch', 'buzzybuzz', 'circlethrow', 'clearsmog', 'doubleironbash', 'dragondarts', 'dragontail', 'endeavor', 'facade', 'firefang', 'flipturn', 'freezedry', 'frustration', 'geargrind', 'grassknot', 'gyroball', 'hex', 'icefang', 'iceshard', 'iciclespear', 'knockoff', 'lowkick', 'machpunch', 'nightshade', 'nuzzle', 'pikapapow', 'psychocut', 'pursuit', 'quickattack', 'rapidspin', 'return', 'rockblast', 'scorchingsands', 'seismictoss', 'shadowclaw', 'shadowsneak', 'sizzlyslide', 'storedpower', 'stormthrow', 'suckerpunch', 'superfang', 'surgingstrikes', 'tailslap', 'tripleaxel', 'uturn', 'veeveevolley', 'voltswitch', 'watershuriken', 'weatherball', + 'accelerock', 'acrobatics', 'aquacutter', 'avalanche', 'barbbarrage', 'bonemerang', 'bouncybubble', 'bulletpunch', 'buzzybuzz', 'ceaselessedge', 'circlethrow', 'clearsmog', 'doubleironbash', 'dragondarts', 'dragontail', 'drainingkiss', 'endeavor', 'facade', 'firefang', 'flipturn', 'flowertrick', 'freezedry', 'frustration', 'geargrind', 'grassknot', 'gyroball', 'icefang', 'iceshard', 'iciclespear', 'infernalparade', 'knockoff', 'lastrespects', 'lowkick', 'machpunch', 'mortalspin', 'mysticalpower', 'naturesmadness', 'nightshade', 'nuzzle', 'pikapapow', 'populationbomb', 'psychocut', 'psyshieldbash', 'pursuit', 'quickattack', 'ragefist', 'rapidspin', 'return', 'rockblast', 'ruination', 'saltcure', 'scorchingsands', 'seismictoss', 'shadowclaw', 'shadowsneak', 'sizzlyslide', 'stoneaxe', 'storedpower', 'stormthrow', 'suckerpunch', 'superfang', 'surgingstrikes', 'tailslap', 'trailblaze', 'tripleaxel', 'tripledive', 'twinbeam', 'uturn', 'veeveevolley', 'voltswitch', 'watershuriken', 'weatherball', ] as ID[] as readonly ID[]; static readonly BAD_STRONG_MOVES = [ - 'beakblast', 'belch', 'burnup', 'crushclaw', 'doomdesire', 'dragonrush', 'dreameater', 'eggbomb', 'firepledge', 'flyingpress', 'futuresight', 'grasspledge', 'hyperbeam', 'hyperfang', 'hyperspacehole', 'jawlock', 'landswrath', 'lastresort', 'megakick', 'megapunch', 'mistyexplosion', 'muddywater', 'nightdaze', 'pollenpuff', 'rockclimb', 'selfdestruct', 'shelltrap', 'skyuppercut', 'slam', 'strength', 'submission', 'synchronoise', 'takedown', 'thrash', 'uproar', 'waterpledge', + 'belch', 'burnup', 'crushclaw', 'dragonrush', 'dreameater', 'eggbomb', 'firepledge', 'flyingpress', 'grasspledge', 'hyperbeam', 'hyperfang', 'hyperspacehole', 'jawlock', 'landswrath', 'megakick', 'megapunch', 'mistyexplosion', 'muddywater', 'nightdaze', 'pollenpuff', 'rockclimb', 'selfdestruct', 'shelltrap', 'skyuppercut', 'slam', 'strength', 'submission', 'synchronoise', 'takedown', 'thrash', 'uproar', 'waterpledge', ] as ID[] as readonly ID[]; static readonly GOOD_DOUBLES_MOVES = [ - 'allyswitch', 'bulldoze', 'coaching', 'electroweb', 'faketears', 'fling', 'followme', 'healpulse', 'helpinghand', 'junglehealing', 'lifedew', 'muddywater', 'pollenpuff', 'psychup', 'ragepowder', 'safeguard', 'skillswap', 'snipeshot', 'wideguard', + 'allyswitch', 'bulldoze', 'coaching', 'electroweb', 'faketears', 'fling', 'followme', 'healpulse', 'helpinghand', 'junglehealing', 'lifedew', 'lunarblessing', 'muddywater', 'pollenpuff', 'psychup', 'ragepowder', 'safeguard', 'skillswap', 'snipeshot', 'wideguard', ] as ID[] as readonly ID[]; getBaseResults() { if (!this.species) return this.getDefaultResults(); @@ -1442,9 +1468,6 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { /^battle(spot|stadium|festival)/.test(format) || format.startsWith('vgc') || (dex.gen === 9 && this.formatType !== 'natdex'); - const abilityid = this.set ? toID(this.set.ability) : '' as ID; - const itemid = this.set ? toID(this.set.item) : '' as ID; - let learnsetid = this.firstLearnsetid(species.id); let moves: string[] = []; let sketchMoves: string[] = []; @@ -1566,7 +1589,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { let usableMoves: SearchRow[] = []; let uselessMoves: SearchRow[] = []; for (const id of moves) { - const isUsable = this.moveIsNotUseless(id as ID, species, abilityid, itemid, moves); + const isUsable = this.moveIsNotUseless(id as ID, species, moves, this.set); if (isUsable) { if (!usableMoves.length) usableMoves.push(['header', "Moves"]); usableMoves.push(['move', id as ID]); @@ -1580,7 +1603,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { uselessMoves.push(['header', "Useless sketched moves"]); } for (const id of sketchMoves) { - const isUsable = this.moveIsNotUseless(id as ID, species, abilityid, itemid, sketchMoves); + const isUsable = this.moveIsNotUseless(id as ID, species, sketchMoves, this.set); if (isUsable) { usableMoves.push(['move', id as ID]); } else { From e637fe5550d24c5429bfb4e66c6ee1f794e2e313 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Sat, 7 Jan 2023 16:35:05 -0600 Subject: [PATCH 387/770] Bypass https on localhost (#2078) --- js/client.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/js/client.js b/js/client.js index 399031b749..1ac6061887 100644 --- a/js/client.js +++ b/js/client.js @@ -393,6 +393,8 @@ function toId() { }, focused: true, initialize: function () { + // Gotta cache this since backbone removes it + this.query = window.location.search; window.app = this; this.initializeRooms(); this.initializePopups(); @@ -753,11 +755,15 @@ function toId() { // anyway, this affects SockJS because it makes HTTP requests to localhost // but it turns out that making direct WebSocket connections to localhost is // still supported, so we'll just bypass SockJS and use WebSocket directly. + var possiblePort = new URL(document.location + self.query).searchParams.get('port'); + // We need to bypass the port as well because on most modern browsers, http gets forced + // to https, which means a ws connection is made to port 443 instead of wherever it's actually running, + // thus ensuring a failed connection. + var port = possiblePort || Config.server.port; console.log("Bypassing SockJS for localhost"); - console.log('ws' + protocol.slice('4') + '://' + Config.server.host + ':' + Config.server.port + Config.sockjsprefix + '/websocket'); - return new WebSocket( - 'ws' + protocol.slice('4') + '://' + Config.server.host + ':' + Config.server.port + Config.sockjsprefix + '/websocket' - ); + var url = 'ws://' + Config.server.host + ':' + port + Config.sockjsprefix + '/websocket'; + console.log(url); + return new WebSocket(url); } return new SockJS( protocol + '://' + Config.server.host + ':' + Config.server.port + Config.sockjsprefix, From ef337ac41d0112d19b3f3f6ad7ffe65c5d2d687d Mon Sep 17 00:00:00 2001 From: HoeenHero Date: Mon, 9 Jan 2023 09:19:45 -0500 Subject: [PATCH 388/770] Prevent Tera Type loss when importing backed up teams (#2081) --- js/storage.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/storage.js b/js/storage.js index 7070c0020d..98f4119856 100644 --- a/js/storage.js +++ b/js/storage.js @@ -1128,6 +1128,7 @@ Storage.importTeam = function (buffer, teams) { } line = $.trim(line.substr(bracketIndex + 1)); } + var gen = parseInt(format[3], 10) || 6; if (teams.length && typeof teams[teams.length - 1].team !== 'string') { teams[teams.length - 1].team = Storage.packTeam(teams[teams.length - 1].team); } @@ -1140,6 +1141,7 @@ Storage.importTeam = function (buffer, teams) { teams.push({ name: line, format: format, + gen: gen, team: team, capacity: capacity, folder: folder, From 618e8655a094308d89b66559f4a76678cd6d6d13 Mon Sep 17 00:00:00 2001 From: Alexander B <4866817+MathyFurret@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:23:36 -0600 Subject: [PATCH 389/770] Fix Terastallized Pokemon tracking (#2072) --- src/battle.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/battle.ts b/src/battle.ts index 12d4c2ed92..1d946d0238 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -117,6 +117,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { this.shiny = data.shiny; this.gender = data.gender || 'N'; this.ident = data.ident; + this.terastallized = data.terastallized || ''; this.searchid = data.searchid; this.sprite = side.battle.scene.addPokemonSprite(this); @@ -865,6 +866,7 @@ export class Side { pokemon.maxhp = oldpokemon.maxhp; pokemon.hpcolor = oldpokemon.hpcolor; pokemon.status = oldpokemon.status; + pokemon.terastallized = oldpokemon.terastallized; pokemon.copyVolatileFrom(oldpokemon, true); pokemon.statusData = {...oldpokemon.statusData}; // we don't know anything about the illusioned pokemon except that it's not fainted @@ -872,6 +874,7 @@ export class Side { oldpokemon.fainted = false; oldpokemon.hp = oldpokemon.maxhp; oldpokemon.status = '???'; + oldpokemon.terastallized = ''; } this.active[slot] = pokemon; pokemon.slot = slot; @@ -943,6 +946,8 @@ export class Side { pokemon.fainted = true; pokemon.hp = 0; pokemon.terastallized = ''; + pokemon.details = pokemon.details.replace(/, tera:[a-z]+/i, ''); + pokemon.searchid = pokemon.searchid.replace(/, tera:[a-z]+/i, ''); if (pokemon.side.faintCounter < 100) pokemon.side.faintCounter++; this.battle.scene.animFaint(pokemon); @@ -962,6 +967,7 @@ export interface PokemonDetails { shiny: boolean; gender: GenderName | ''; ident: string; + terastallized: string; searchid: string; } export interface PokemonHealth { @@ -3117,6 +3123,10 @@ export class Battle { output.ident = (!isTeamPreview ? pokemonid : ''); output.searchid = (!isTeamPreview ? `${pokemonid}|${details}` : ''); let splitDetails = details.split(', '); + if (splitDetails[splitDetails.length - 1].startsWith('tera:')) { + output.terastallized = splitDetails[splitDetails.length - 1].slice(5); + splitDetails.pop(); + } if (splitDetails[splitDetails.length - 1] === 'shiny') { output.shiny = true; splitDetails.pop(); @@ -3534,6 +3544,7 @@ export class Battle { let slot = poke.slot; poke.healthParse(args[3]); poke.removeVolatile('itemremoved' as ID); + poke.terastallized = args[2].match(/tera:([a-z]+)$/i)?.[1] || ''; if (args[0] === 'switch') { if (poke.side.active[slot]) { poke.side.switchOut(poke.side.active[slot]!, kwArgs); From 2c4a08ca12af51c3cd32fa916bc3d706ee339d39 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Mon, 9 Jan 2023 16:24:20 -0600 Subject: [PATCH 390/770] Remember Ability Shield on '-block' messages too (#2075) --- src/battle.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/battle.ts b/src/battle.ts index 1d946d0238..405a2dd689 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2055,6 +2055,9 @@ export class Battle { case 'protectivepads': poke.item = 'Protective Pads'; break; + case 'abilityshield': + poke.item = 'Ability Shield'; + break; } this.log(args, kwArgs); break; From 2919985a9bfadb97dbd3604298fcd236f954621f Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 9 Jan 2023 17:25:08 -0500 Subject: [PATCH 391/770] Fix Palafin sprite not always changing to Hero forme (#2080) --- src/battle-animations.ts | 37 +++++++++++++++++++++---------------- src/battle.ts | 11 ++--------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 84bef74f50..1ad265741d 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -2522,27 +2522,32 @@ export class PokemonSprite extends Sprite { xscale: 0, opacity: 0, }, sp)); - this.$el.animate(this.scene.pos({ - x: this.x, - y: this.y, - z: this.z, - yscale: 0, - xscale: 0, - opacity: 0.3, - }, oldsp), 300, () => { - if (this.cryurl && doCry) { - BattleSound.playEffect(this.cryurl); - } + if (speciesid === 'palafinhero') { this.$el.replaceWith($newEl); this.$el = $newEl; - this.$el.animate(scene.pos({ + } else { + this.$el.animate(this.scene.pos({ x: this.x, y: this.y, z: this.z, - opacity: 1, - }, sp), 300); - }); - this.scene.wait(500); + yscale: 0, + xscale: 0, + opacity: 0.3, + }, oldsp), 300, () => { + if (this.cryurl && doCry) { + BattleSound.playEffect(this.cryurl); + } + this.$el.replaceWith($newEl); + this.$el = $newEl; + this.$el.animate(scene.pos({ + x: this.x, + y: this.y, + z: this.z, + opacity: 1, + }, sp), 300); + }); + this.scene.wait(500); + } this.scene.updateSidebar(pokemon.side); if (isPermanent) { diff --git a/src/battle.ts b/src/battle.ts index 405a2dd689..7561c7a712 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2407,15 +2407,8 @@ export class Battle { poke.details = args[2]; poke.searchid = args[1].substr(0, 2) + args[1].substr(3) + '|' + args[2]; - if (poke.getSpeciesForme() === 'Palafin-Hero') { - poke.sprite.sp = Dex.getSpriteData(poke, poke.sprite.isFrontSprite, { - gen: poke.sprite.scene.gen, - mod: poke.sprite.scene.mod, - }); - poke.sprite.oldsp = null; - } else { - this.scene.animTransform(poke, true, true); - } + let isCustomAnim = species.id !== 'palafinhero'; + this.scene.animTransform(poke, isCustomAnim, true); this.log(args, kwArgs); break; } From 81bbeb7af48feec79358c5bfbf562e7ac6ee357f Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Wed, 11 Jan 2023 13:14:09 -0600 Subject: [PATCH 392/770] Add a tournaments button to the homepage (#2084) --- js/client-mainmenu.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index a476a38db2..c730775d43 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -50,8 +50,11 @@ buf += '

        '; } - buf += ''; + buf += ''; buf += ''; From b94e2fea22d09f625f8e5fed5d96e2cfce1157d5 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:37:20 -0500 Subject: [PATCH 393/770] Fix message for Primal Weather blocking Snowscape (#2082) --- src/battle-text-parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index a62603afe6..84f23fc323 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -1027,7 +1027,7 @@ class BattleTextParser { const line1 = this.maybeAbility(kwArgs.from, kwArgs.of || pokemon); let templateId = 'block'; if (['desolateland', 'primordialsea'].includes(blocker) && - !['sunnyday', 'raindance', 'sandstorm', 'hail', 'snow'].includes(id)) { + !['sunnyday', 'raindance', 'sandstorm', 'hail', 'snowscape', 'chillyreception'].includes(id)) { templateId = 'blockMove'; } else if (blocker === 'uproar' && kwArgs.msg) { templateId = 'blockSelf'; From d7732d08f44817600baf9061c4ff03d9779c7c66 Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Thu, 12 Jan 2023 19:38:16 -0600 Subject: [PATCH 394/770] Fix Clear Amulet and Lingering Aroma activations (#2083) --- src/battle-text-parser.ts | 2 +- src/battle.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 84f23fc323..3a29812354 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -144,7 +144,7 @@ class BattleTextParser { kwArgs.item = arg3; } else if (id === 'magnitude') { kwArgs.number = arg3; - } else if (id === 'skillswap' || id === 'mummy' || id === 'wanderingspirit') { + } else if (id === 'skillswap' || id === 'mummy' || id === 'lingeringaroma' || id === 'wanderingspirit') { kwArgs.ability = arg3; kwArgs.ability2 = arg4; } else if ([ diff --git a/src/battle.ts b/src/battle.ts index 7561c7a712..6148f2e451 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1991,7 +1991,11 @@ export class Battle { let effect = Dex.getEffect(args[2]); let fromeffect = Dex.getEffect(kwArgs.from); let ofpoke = this.getPokemon(kwArgs.of); - this.activateAbility(ofpoke || poke, fromeffect); + if (fromeffect.id === 'clearamulet') { + ofpoke!.item = 'Clear Amulet'; + } else { + this.activateAbility(ofpoke || poke, fromeffect); + } switch (effect.id) { case 'brn': this.scene.resultAnim(poke, 'Already burned', 'neutral'); From 6ee1b90c46964ce81256e79b84229ade184199c0 Mon Sep 17 00:00:00 2001 From: Alexander B <4866817+MathyFurret@users.noreply.github.com> Date: Thu, 12 Jan 2023 19:39:31 -0600 Subject: [PATCH 395/770] Tooltips: Hide Tera Type for Terastal Clause (#2086) --- src/battle-tooltips.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 8612218c2d..bc9660ebc3 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -805,7 +805,7 @@ class BattleTooltips { text += types.map(type => Dex.getTypeIcon(type)).join(' '); if (pokemon.terastallized) { text += ` (base: ${this.getPokemonTypes(pokemon, true).map(type => Dex.getTypeIcon(type)).join(' ')})`; - } else if (serverPokemon?.teraType) { + } else if (serverPokemon?.teraType && !this.battle.rules['Terastal Clause']) { text += ` (Tera Type: ${Dex.getTypeIcon(serverPokemon.teraType)})`; } text += `

    `; From 1760028ce5bfa5bca1271adf384a95b09d159f66 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:39:54 -0500 Subject: [PATCH 396/770] Fix Protosynthesis and Quark Drive getting copied for Baton Pass (#2087) --- src/battle.ts | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index 6148f2e451..232c676e4f 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -438,26 +438,16 @@ export class Pokemon implements PokemonDetails, PokemonHealth { this.volatiles = pokemon.volatiles; // this.lastMove = pokemon.lastMove; // I think if (!copySource) { - delete this.volatiles['airballoon']; - delete this.volatiles['attract']; - delete this.volatiles['autotomize']; - delete this.volatiles['disable']; - delete this.volatiles['encore']; - delete this.volatiles['foresight']; - delete this.volatiles['gmaxchistrike']; - delete this.volatiles['imprison']; - delete this.volatiles['laserfocus']; - delete this.volatiles['mimic']; - delete this.volatiles['miracleeye']; - delete this.volatiles['nightmare']; - delete this.volatiles['smackdown']; - delete this.volatiles['stockpile1']; - delete this.volatiles['stockpile2']; - delete this.volatiles['stockpile3']; - delete this.volatiles['torment']; - delete this.volatiles['typeadd']; - delete this.volatiles['typechange']; - delete this.volatiles['yawn']; + const volatilesToRemove = [ + 'airballoon', 'attract', 'autotomize', 'disable', 'encore', 'foresight', 'gmaxchistrike', 'imprison', 'laserfocus', 'mimic', 'miracleeye', 'nightmare', 'saltcure', 'smackdown', 'stockpile1', 'stockpile2', 'stockpile3', 'torment', 'typeadd', 'typechange', 'yawn', + ]; + for (const statName of Dex.statNamesExceptHP) { + volatilesToRemove.push('protosynthesis' + statName); + volatilesToRemove.push('quarkdrive' + statName); + } + for (const volatile of volatilesToRemove) { + delete this.volatiles[volatile]; + } } if (copySource === 'shedtail') { for (let i in this.volatiles) { From 1c0b3ca1750ec3757d2f97ad569ff177074fa67d Mon Sep 17 00:00:00 2001 From: qwertystrargs <119243068+qwertystrargs@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:53:34 -0500 Subject: [PATCH 397/770] Tooltips: Align Tera reminders with types (#2085) --- src/battle-tooltips.ts | 6 +++--- style/battle.css | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index bc9660ebc3..482a46ebdf 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -802,11 +802,11 @@ class BattleTooltips { } else if (clientPokemon?.volatiles.typechange || clientPokemon?.volatiles.typeadd) { text += `(Type changed)
    `; } - text += types.map(type => Dex.getTypeIcon(type)).join(' '); + text += `${types.map(type => Dex.getTypeIcon(type)).join(' ')}`; if (pokemon.terastallized) { - text += ` (base: ${this.getPokemonTypes(pokemon, true).map(type => Dex.getTypeIcon(type)).join(' ')})`; + text += `    (base: ${this.getPokemonTypes(pokemon, true).map(type => Dex.getTypeIcon(type)).join(' ')})`; } else if (serverPokemon?.teraType && !this.battle.rules['Terastal Clause']) { - text += ` (Tera Type: ${Dex.getTypeIcon(serverPokemon.teraType)})`; + text += `    (Tera Type: ${Dex.getTypeIcon(serverPokemon.teraType)})`; } text += ``; } diff --git a/style/battle.css b/style/battle.css index 19458f93b7..5f0ddb04c4 100644 --- a/style/battle.css +++ b/style/battle.css @@ -789,6 +789,9 @@ License: GPLv2 #tooltipwrapper .tooltip p.section { border-top: 1px solid #888888; } +#tooltipwrapper .tooltip .textaligned-typeicons img { + vertical-align: text-bottom; +} #tooltipwrapper.tooltip-locked { pointer-events: auto; } From ad261880c3e95e071022debcbdd9f6ae2a18e86d Mon Sep 17 00:00:00 2001 From: Hisuian Zoroark <96159984+HisuianZoroark@users.noreply.github.com> Date: Sun, 15 Jan 2023 14:28:01 -0500 Subject: [PATCH 398/770] Tooltips: Don't show drop for same Ruin Abilities (#2088) --- src/battle-tooltips.ts | 24 ++++++++++++++++-------- src/battle.ts | 7 +------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 482a46ebdf..0e5e663a6d 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1215,17 +1215,25 @@ class BattleTooltips { if (ability === 'furcoat') { stats.def *= 2; } - if (this.battle.abilityActive('Vessel of Ruin', pokemon)) { - stats.spa = Math.floor(stats.spa * 0.75); + if (this.battle.abilityActive('Vessel of Ruin')) { + if (ability !== 'vesselofruin') { + stats.spa = Math.floor(stats.spa * 0.75); + } } - if (this.battle.abilityActive('Sword of Ruin', pokemon)) { - stats.def = Math.floor(stats.def * 0.75); + if (this.battle.abilityActive('Sword of Ruin')) { + if (ability !== 'swordofruin') { + stats.def = Math.floor(stats.def * 0.75); + } } - if (this.battle.abilityActive('Tablets of Ruin', pokemon)) { - stats.atk = Math.floor(stats.atk * 0.75); + if (this.battle.abilityActive('Tablets of Ruin')) { + if (ability !== 'tabletsofruin') { + stats.atk = Math.floor(stats.atk * 0.75); + } } - if (this.battle.abilityActive('Beads of Ruin', pokemon)) { - stats.spd = Math.floor(stats.spd * 0.75); + if (this.battle.abilityActive('Beads of Ruin')) { + if (ability !== 'beadsofruin') { + stats.spd = Math.floor(stats.spd * 0.75); + } } const sideConditions = this.battle.mySide.sideConditions; if (sideConditions['tailwind']) { diff --git a/src/battle.ts b/src/battle.ts index 232c676e4f..9aada9d806 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -1192,18 +1192,13 @@ export class Battle { } return false; } - abilityActive(abilities: string | string[], excludePokemon?: Pokemon | ServerPokemon | null) { + abilityActive(abilities: string | string[]) { if (typeof abilities === 'string') abilities = [abilities]; if (this.ngasActive()) { abilities = abilities.filter(a => this.dex.abilities.get(a).isPermanent); if (!abilities.length) return false; } for (const active of this.getAllActive()) { - if (active === excludePokemon) continue; - if (excludePokemon && this.pokemonControlled === 1 && - active.ident.slice(0, 2) === excludePokemon.ident.slice(0, 2)) { - continue; - } if (abilities.includes(active.ability) && !active.volatiles['gastroacid']) { return true; } From 9883683c108258104768a3c7bd1f9d2839ff18b9 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sun, 15 Jan 2023 12:29:18 -0700 Subject: [PATCH 399/770] Teambuilder: Update OM support for Gen 9 (#2089) --- js/client-teambuilder.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index fd6e43c572..4857d76857 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -2964,23 +2964,24 @@ var id = toID(e.currentTarget.value); if (id in BattleAliases) id = toID(BattleAliases[id]); var val = ''; + var format = this.curTeam.format; switch (name) { case 'pokemon': val = (id in BattlePokedex ? this.curTeam.dex.species.get(e.currentTarget.value).name : ''); break; case 'ability': - if (id in BattleItems && this.curTeam.format == "gen8dualwielding") { + if (id in BattleItems && format && format.endsWith("dualwielding")) { val = BattleItems[id].name; - } else if (id in BattleMovedex && this.curTeam.format == "gen8trademarked") { + } else if (id in BattleMovedex && format && format.endsWith("trademarked")) { val = BattleMovedex[id].name; } else { val = (id in BattleAbilities ? BattleAbilities[id].name : ''); } break; case 'item': - if (id in BattleMovedex && this.curTeam.format == "gen8fortemons") { + if (id in BattleMovedex && format && format.endsWith("fortemons")) { val = BattleMovedex[id].name; - } else if (id in BattleAbilities && this.curTeam.format == "gen8multibility") { + } else if (id in BattleAbilities && format && format.endsWith("multibility")) { val = BattleAbilities[id].name; } else { val = (id in BattleItems ? BattleItems[id].name : ''); From c35b8f18253ac2b1164e2088bc917bc976ebe250 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Fri, 20 Jan 2023 17:28:01 -0500 Subject: [PATCH 400/770] Fix Tera permanently replacing sprite (#2090) --- src/battle-animations.ts | 3 +++ src/battle-scene-stub.ts | 1 + src/battle.ts | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/battle-animations.ts b/src/battle-animations.ts index 1ad265741d..612ec90b54 100644 --- a/src/battle-animations.ts +++ b/src/battle-animations.ts @@ -1477,6 +1477,9 @@ export class BattleScene implements BattleSceneStub { animDragOut(pokemon: Pokemon) { return pokemon.sprite.animDragOut(pokemon); } + resetStatbar(pokemon: Pokemon, startHidden?: boolean) { + return pokemon.sprite.resetStatbar(pokemon, startHidden); + } updateStatbar(pokemon: Pokemon, updatePrevhp?: boolean, updateHp?: boolean) { return pokemon.sprite.updateStatbar(pokemon, updatePrevhp, updateHp); } diff --git a/src/battle-scene-stub.ts b/src/battle-scene-stub.ts index 99a8dde092..050ba74e2a 100644 --- a/src/battle-scene-stub.ts +++ b/src/battle-scene-stub.ts @@ -63,6 +63,7 @@ export class BattleSceneStub { animUnsummon(pokemon: Pokemon, instant?: boolean) { } animDragIn(pokemon: Pokemon, slot: number) { } animDragOut(pokemon: Pokemon) { } + resetStatbar(pokemon: Pokemon, startHidden?: boolean) { } updateStatbar(pokemon: Pokemon, updatePrevhp?: boolean, updateHp?: boolean) { } updateStatbarIfExists(pokemon: Pokemon, updatePrevhp?: boolean, updateHp?: boolean) { } animTransform(pokemon: Pokemon, isCustomAnim?: boolean, isPermanent?: boolean) { } diff --git a/src/battle.ts b/src/battle.ts index 9aada9d806..d3f3bd548f 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -2469,7 +2469,8 @@ export class Battle { poke.terastallized = type; poke.details += `, tera:${type}`; poke.searchid += `, tera:${type}`; - this.scene.animTransform(poke, true, true); + this.scene.animTransform(poke, true); + this.scene.resetStatbar(poke); this.log(args, kwArgs); break; } From a12563218ec0ec61f667a67bc4f8fb29ee6d6d2d Mon Sep 17 00:00:00 2001 From: Marty-D Date: Fri, 20 Jan 2023 17:28:24 -0500 Subject: [PATCH 401/770] Prepare for renaming Paldean Tauros forms --- src/battle-dex-data.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/battle-dex-data.ts b/src/battle-dex-data.ts index ba3c27c150..9950d47516 100644 --- a/src/battle-dex-data.ts +++ b/src/battle-dex-data.ts @@ -370,6 +370,9 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { taurospaldea: 1020 + 224, taurospaldeafire: 1020 + 225, taurospaldeawater: 1020 + 226, + taurospaldeacombat: 1020 + 224, + taurospaldeablaze: 1020 + 225, + taurospaldeaaqua: 1020 + 226, wooperpaldea: 1020 + 227, oinkolognef: 1020 + 228, palafinhero: 1020 + 229, From 07074574258956117f01bdf57e329da7603156e8 Mon Sep 17 00:00:00 2001 From: Marty Date: Sat, 21 Jan 2023 12:09:19 -0500 Subject: [PATCH 402/770] Update Tauros form names --- src/battle-dex-search.ts | 2 +- src/battle-tooltips.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/battle-dex-search.ts b/src/battle-dex-search.ts index fdceb92618..2c54715409 100644 --- a/src/battle-dex-search.ts +++ b/src/battle-dex-search.ts @@ -1562,7 +1562,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { species = dex.species.get(pokemon.battleOnly); } const excludedForme = (s: Species) => [ - 'Alola', 'Alola-Totem', 'Galar', 'Galar-Zen', 'Hisui', 'Paldea', 'Paldea-Fire', 'Paldea-Water', + 'Alola', 'Alola-Totem', 'Galar', 'Galar-Zen', 'Hisui', 'Paldea', 'Paldea-Combat', 'Paldea-Blaze', 'Paldea-Aqua', ].includes(s.forme); if (baseSpecies.otherFormes && !['Wormadam', 'Urshifu'].includes(baseSpecies.baseSpecies)) { if (!excludedForme(species)) speciesTypes.push(...baseSpecies.types); diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 0e5e663a6d..0a8bd8f6b9 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1456,13 +1456,13 @@ class BattleTooltips { // Raging Bull's type depends on the Tauros forme if (move.id === 'ragingbull') { switch (pokemon.getSpeciesForme()) { - case 'Tauros-Paldea': + case 'Tauros-Paldea-Combat': moveType = 'Fighting'; break; - case 'Tauros-Paldea-Fire': + case 'Tauros-Paldea-Blaze': moveType = 'Fire'; break; - case 'Tauros-Paldea-Water': + case 'Tauros-Paldea-Aqua': moveType = 'Water'; break; } From ae9588b08e9b65d49c3c48c33d369fc143422fde Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 21 Jan 2023 12:18:08 -0500 Subject: [PATCH 403/770] Fix Tera Type not exporting when backing up all teams (#2094) --- js/storage.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/js/storage.js b/js/storage.js index 98f4119856..c68acaa0b6 100644 --- a/js/storage.js +++ b/js/storage.js @@ -646,7 +646,7 @@ Storage.unpackAllTeams = function (buffer) { if (buffer.charAt(0) === '[' && $.trim(buffer).indexOf('\n') < 0) { // old format return JSON.parse(buffer).map(function (oldTeam) { - var format = oldTeam.format || 'gen8'; + var format = oldTeam.format || 'gen9'; var capacity = 6; if (format && format.slice(0, 3) !== 'gen') format = 'gen6' + format; if (format && format.endsWith('-box')) { @@ -656,6 +656,7 @@ Storage.unpackAllTeams = function (buffer) { return { name: oldTeam.name || '', format: format, + gen: parseInt(format[3], 10) || 6, team: Storage.packTeam(oldTeam.team), capacity: capacity, folder: '', @@ -675,11 +676,12 @@ Storage.unpackLine = function (line) { var isBox = line.slice(0, bracketIndex).endsWith('-box'); var slashIndex = line.lastIndexOf('/', pipeIndex); if (slashIndex < 0) slashIndex = bracketIndex; // line.slice(slashIndex + 1, pipeIndex) will be '' - var format = bracketIndex > 0 ? line.slice(0, isBox ? bracketIndex - 4 : bracketIndex) : 'gen8'; + var format = bracketIndex > 0 ? line.slice(0, isBox ? bracketIndex - 4 : bracketIndex) : 'gen9'; if (format && format.slice(0, 3) !== 'gen') format = 'gen6' + format; return { name: line.slice(slashIndex + 1, pipeIndex), format: format, + gen: parseInt(format[3], 10) || 6, team: line.slice(pipeIndex + 1), capacity: isBox ? 24 : 6, folder: line.slice(bracketIndex + 1, slashIndex > 0 ? slashIndex : bracketIndex + 1), @@ -1116,7 +1118,7 @@ Storage.importTeam = function (buffer, teams) { } else if (line.substr(0, 3) === '===' && teams) { team = []; line = $.trim(line.substr(3, line.length - 6)); - var format = 'gen8'; + var format = 'gen9'; var capacity = 6; var bracketIndex = line.indexOf(']'); if (bracketIndex >= 0) { @@ -1128,7 +1130,6 @@ Storage.importTeam = function (buffer, teams) { } line = $.trim(line.substr(bracketIndex + 1)); } - var gen = parseInt(format[3], 10) || 6; if (teams.length && typeof teams[teams.length - 1].team !== 'string') { teams[teams.length - 1].team = Storage.packTeam(teams[teams.length - 1].team); } @@ -1141,7 +1142,7 @@ Storage.importTeam = function (buffer, teams) { teams.push({ name: line, format: format, - gen: gen, + gen: parseInt(format[3], 10) || 6, team: team, capacity: capacity, folder: folder, @@ -1566,7 +1567,7 @@ Storage.nwLoadTeamFile = function (filename, localApp) { return; } - var format = 'gen8'; + var format = 'gen9'; var capacity = 6; var bracketIndex = line.indexOf(']'); if (bracketIndex >= 0) { @@ -1584,6 +1585,7 @@ Storage.nwLoadTeamFile = function (filename, localApp) { self.teams.push({ name: line, format: format, + gen: parseInt(format[3], 10) || 6, team: Storage.packTeam(Storage.importTeam('' + data)), capacity: capacity, folder: folder, From 3fe827e2d132f749893b47f249f8b34567c419c0 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 29 Jan 2023 23:47:59 +0530 Subject: [PATCH 404/770] Fix Cosmetic forme sprites not showing in Gen 9 (#2096) --- js/client-teambuilder.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 4857d76857..15f65a2be4 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -3430,11 +3430,12 @@ var spriteSize = 96; var spriteDim = 'width: 96px; height: 96px;'; - var gen = {1:'gen1', 2:'gen2', 3:'gen3', 4:'gen4', 5:'gen5', 6:'dex', 7:'dex', 8:'dex'}[Math.max(this.room.curTeam.gen, species.gen)]; + var gen = Math.max(this.room.curTeam.gen, species.gen); + var dir = gen > 5 ? 'dex' : 'gen' + gen; if (Dex.prefs('nopastgens')) gen = 'dex'; - if (Dex.prefs('bwgfx') && gen === 'dex') gen = 'gen5'; - spriteDir += gen; - if (gen === 'dex') { + if (Dex.prefs('bwgfx') && dir === 'dex') gen = 'gen5'; + spriteDir += dir; + if (dir === 'dex') { spriteSize = 120; spriteDim = 'width: 120px; height: 120px;'; } From 5cd9238e60802f37f3ad9c5bf5a0be2820b910c8 Mon Sep 17 00:00:00 2001 From: Alexander B <4866817+MathyFurret@users.noreply.github.com> Date: Sun, 29 Jan 2023 12:21:09 -0600 Subject: [PATCH 405/770] Tooltips: Fix Steely Spirit to boost ally moves (#2097) --- src/battle-tooltips.ts | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 0a8bd8f6b9..c460b9e630 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1849,9 +1849,6 @@ class BattleTooltips { if (move.flags['contact']) { value.abilityModify(1.3, "Tough Claws"); } - if (moveType === 'Steel') { - value.abilityModify(1.5, "Steely Spirit"); - } if (move.flags['sound']) { value.abilityModify(1.3, "Punk Rock"); } @@ -1904,22 +1901,20 @@ class BattleTooltips { auraBoosted = 'Dark Aura'; } else if (allyAbility === 'Aura Break') { auraBroken = true; - } else if (allyAbility === 'Battery') { - if (ally !== pokemon && move.category === 'Special') { - value.modify(1.3, 'Battery'); - } - } else if (allyAbility === 'Power Spot') { - if (ally !== pokemon) { - value.modify(1.3, 'Power Spot'); - } + } else if (allyAbility === 'Battery' && ally !== pokemon && move.category === 'Special') { + value.modify(1.3, 'Battery'); + } else if (allyAbility === 'Power Spot' && ally !== pokemon) { + value.modify(1.3, 'Power Spot'); + } else if (allyAbility === 'Steely Spirit' && moveType === 'Steel') { + value.modify(1.5, 'Steely Spirit'); } } for (const foe of pokemon.side.foe.active) { if (!foe || foe.fainted) continue; - if (foe.ability === 'Fairy Aura') { - if (moveType === 'Fairy') auraBoosted = 'Fairy Aura'; - } else if (foe.ability === 'Dark Aura') { - if (moveType === 'Dark') auraBoosted = 'Dark Aura'; + if (foe.ability === 'Fairy Aura' && moveType === 'Fairy') { + auraBoosted = 'Fairy Aura'; + } else if (foe.ability === 'Dark Aura' && moveType === 'Dark') { + auraBoosted = 'Dark Aura'; } else if (foe.ability === 'Aura Break') { auraBroken = true; } From 73eb46cc66db03a02a0ad361b9cebd7bba10ad85 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 2 Feb 2023 01:16:35 +0530 Subject: [PATCH 406/770] Properly handle Orichalcum Pulse activation messages (#2098) --- src/battle-text-parser.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 3a29812354..6d3ff06d03 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -788,9 +788,6 @@ class BattleTextParser { return this.template('upkeep', weather, 'NODEFAULT'); } const line1 = this.maybeAbility(kwArgs.from, kwArgs.of); - if (BattleTextParser.effectId(kwArgs.from) === 'orichalcumpulse') { - return line1 + this.template('start', 'orichalcumpulse').replace('[POKEMON]', this.pokemon(kwArgs.of)); - } let template = this.template('start', weather, 'NODEFAULT'); if (!template) template = this.template('startFieldEffect').replace('[EFFECT]', this.effect(weather)); return line1 + template; @@ -865,6 +862,9 @@ class BattleTextParser { if ((id === 'protosynthesis' || id === 'quarkdrive') && kwArgs.fromitem) { templateId = 'activateFromItem'; } + if (id === 'orichalcumpulse' && kwArgs.source) { + templateId = 'start'; + } let template = this.template(templateId, effect, 'NODEFAULT'); if (!template) { if (line1) return line1; // Abilities don't have a default template From 81c72199cd02f1cd6cb216834640627ebadfdc30 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Mon, 27 Feb 2023 16:50:15 -0500 Subject: [PATCH 407/770] Update Pokemon icons sheet --- src/battle-dex.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-dex.ts b/src/battle-dex.ts index 75033860bd..819cfd9882 100644 --- a/src/battle-dex.ts +++ b/src/battle-dex.ts @@ -726,7 +726,7 @@ const Dex = new class implements ModdedDex { let top = Math.floor(num / 12) * 30; let left = (num % 12) * 40; let fainted = ((pokemon as Pokemon | ServerPokemon)?.fainted ? `;opacity:.3;filter:grayscale(100%) brightness(.5)` : ``); - return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v10) no-repeat scroll -${left}px -${top}px${fainted}`; + return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v11) no-repeat scroll -${left}px -${top}px${fainted}`; } getTeambuilderSpriteData(pokemon: any, gen: number = 0): TeambuilderSpriteData { From dffa7bfa052dc3363e3c82504a54b2a0e9128beb Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Mon, 27 Feb 2023 14:50:44 -0700 Subject: [PATCH 408/770] Add new move animations (#2101) --- src/battle-animations-moves.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/battle-animations-moves.ts b/src/battle-animations-moves.ts index 6562e0c096..e42a5f5776 100644 --- a/src/battle-animations-moves.ts +++ b/src/battle-animations-moves.ts @@ -35157,3 +35157,5 @@ BattleMoveAnims['terablast'] = {anim: BattleMoveAnims['swift'].anim}; // placeho BattleMoveAnims['tidyup'] = {anim: BattleMoveAnims['bulkup'].anim}; BattleMoveAnims['trailblaze'] = {anim: BattleMoveAnims['powerwhip'].anim}; BattleMoveAnims['tripledive'] = {anim: BattleMoveAnims['dive'].anim}; +BattleMoveAnims['hydrosteam'] = {anim: BattleMoveAnims['steameruption'].anim}; +BattleMoveAnims['psyblade'] = {anim: BattleMoveAnims['psychocut'].anim}; From 65bff43f6fdbd354fde05bdba72dc884130fbeba Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Wed, 1 Mar 2023 12:47:59 -0700 Subject: [PATCH 409/770] Add tooltips for new moves (#2102) --- src/battle-tooltips.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index c460b9e630..4010f77a32 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1724,6 +1724,12 @@ class BattleTooltips { value.weatherModify(2); } } + if (move.id === 'hydrosteam') { + value.weatherModify(1.5, 'Sunny Day'); + } + if (move.id === 'psyblade' && this.battle.hasPseudoWeather('Electric Terrain')) { + value.modify(1.5, 'Electric Terrain'); + } if (move.id === 'terrainpulse' && pokemon.isGrounded(serverPokemon)) { if ( this.battle.hasPseudoWeather('Electric Terrain') || From 545a434069ac52c1c910672100ca386e53d89a67 Mon Sep 17 00:00:00 2001 From: Kennedy <103935710+KennedyLFC@users.noreply.github.com> Date: Wed, 1 Mar 2023 19:48:40 +0000 Subject: [PATCH 410/770] Update link for Generation 9 Random Battles (#2099) --- website/pages/formatsuggestions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/pages/formatsuggestions.md b/website/pages/formatsuggestions.md index faf356318b..eac7e15469 100644 --- a/website/pages/formatsuggestions.md +++ b/website/pages/formatsuggestions.md @@ -26,9 +26,9 @@ Smogon's Other Metagames formats, on the other hand, is the home for creative us [3]: https://www.smogon.com/forums/forums/other-metagames.531/ -For Random Battles, the [Gen 8 Random Battles sets thread][4] and [past gen Random Battles sets thread][5] are good places to suggest changes. +For Random Battles, the [Gen 9 Random Battles sets thread][4] and [past gen Random Battles sets thread][5] are good places to suggest changes. - [4]: https://www.smogon.com/forums/threads/pokemon-sword-shield-random-battle-sets.3656537/ + [4]: https://www.smogon.com/forums/threads/scarlet-violet-random-battle-sets.3712619/ [5]: https://www.smogon.com/forums/threads/past-gens-random-battle-sets.3674281/ From 9ec5d01e928217642fedba911bebe68a14e4981f Mon Sep 17 00:00:00 2001 From: Marty-D Date: Sun, 5 Mar 2023 19:42:21 -0500 Subject: [PATCH 411/770] Teambuilder: Support NatDex Draft formats properly --- js/client-teambuilder.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 15f65a2be4..5d0358cf33 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -1176,7 +1176,7 @@ var species = this.curTeam.dex.species.get(set.species); var isLetsGo = this.curTeam.format.includes('letsgo'); var isBDSP = this.curTeam.format.includes('bdsp'); - var isNatDex = this.curTeam.format.includes('nationaldex'); + var isNatDex = this.curTeam.format.includes('nationaldex') || this.curTeam.format.includes('natdex'); var buf = '
  • '; if (!set.species) { if (this.deletedSet) { @@ -2605,7 +2605,7 @@ var set = this.curSet; var isLetsGo = this.curTeam.format.includes('letsgo'); var isBDSP = this.curTeam.format.includes('bdsp'); - var isNatDex = this.curTeam.format.includes('nationaldex'); + var isNatDex = this.curTeam.format.includes('nationaldex') || this.curTeam.format.includes('natdex'); var species = this.curTeam.dex.species.get(set.species); if (!set) return; buf += '

    Details

    '; @@ -2704,7 +2704,7 @@ var species = this.curTeam.dex.species.get(set.species); var isLetsGo = this.curTeam.format.includes('letsgo'); var isBDSP = this.curTeam.format.includes('bdsp'); - var isNatDex = this.curTeam.format.includes('nationaldex'); + var isNatDex = this.curTeam.format.includes('nationaldex') || this.curTeam.format.includes('natdex'); // level var level = parseInt(this.$chart.find('input[name=level]').val(), 10); From ac2d1bd81d254c6be34df664f720f015ed6f7a95 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sat, 11 Mar 2023 17:36:48 -0500 Subject: [PATCH 412/770] Build: Fix compiled TS file count (#2074) --- build-tools/compiler.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/build-tools/compiler.js b/build-tools/compiler.js index 5048dc13e2..8250fd321e 100644 --- a/build-tools/compiler.js +++ b/build-tools/compiler.js @@ -186,7 +186,7 @@ function compileToDir(srcDir, destDir, opts = {}) { return total; } -async function compileToFile(srcFile, destFile, opts) { +function compileToFile(srcFile, destFile, opts) { const incremental = opts.incremental; delete opts.incremental; @@ -209,11 +209,12 @@ async function compileToFile(srcFile, destFile, opts) { if (VERBOSE) console.log(src + " ->"); } - const combined = await combineResults(results, { + combineResults(results, { file: path.basename(destFile), sourceRoot: opts.sourceRoot, - }, opts); - outputFileSync(destFile, combined, opts); + }, opts).then(combined => { + outputFileSync(destFile, combined, opts); + }); if (VERBOSE) console.log("-> " + destFile); if (incremental) opts.incremental = true; // incredibly dumb hack to preserve the option From 0cdd61b85a996bff2c6c4d14a747ae52e50377f9 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Mon, 13 Mar 2023 07:36:53 -0400 Subject: [PATCH 413/770] Redesign home page I actually did this redesign way back in April 2022, but I never got around to committing it. I'm doing that now. --- website/index.php | 354 ++++++++++++++++++--------------- website/lib/serverlist.inc.php | 69 +++++++ website/style/global.css | 233 ++++++++++++++++++++++ 3 files changed, 497 insertions(+), 159 deletions(-) create mode 100644 website/lib/serverlist.inc.php create mode 100644 website/style/global.css diff --git a/website/index.php b/website/index.php index a75d108d69..00efd0e528 100644 --- a/website/index.php +++ b/website/index.php @@ -1,81 +1,26 @@ + -// error_reporting(0); + + -include_once __DIR__ . '/../config/config.inc.php'; -include 'style/wrapper.inc.php'; +Pokémon Showdown! battle simulator -function servercmp($a, $b) { - global $usercount; - if ($a['id'] === 'showdown') return -1; - if ($b['id'] === 'showdown') return 1; - if (!empty($usercount[$a['id']])) { - if (!empty($usercount[$b['id']])) { - return $usercount[$b['id']] - $usercount[$a['id']]; - } - return -1; - } else if (!empty($usercount[$b['id']])) { - return 1; - } else if (isset($usercount[$a['id']]) && !isset($usercount[$b['id']])) { - return -1; - } else if (isset($usercount[$b['id']]) && !isset($usercount[$a['id']])) { - return 1; - } - return $a['sortorder'] - $b['sortorder']; -} + -$page = 'home'; -$pageTitle = "Home"; + + + + -includeHeaderTop(); -?> - + .left { + float: left; + width: 560px; + } + .right { + margin-left: 590px; + } + @media (max-width:880px) { + .left iframe { + width: 275px; + height: 144px; + } + .left { + width: 275px; + } + .right { + margin-left: 290px; + } + } + @media (max-width:600px) { + .left { + float: none; + text-align: center; + width: auto; + } + .right { + margin-left: 0; + } + } + .mainbutton { + text-align: center; + } + .mainbutton .button { + background: #3a884f; + background: linear-gradient(to bottom, #4ca363, #276136); + font-size: 16pt; + padding: 12px 20px; + } + .mainbutton .button:hover { + background: linear-gradient(to bottom, #5ac777, #2f7f44); + } + .mainbutton .button:active { + background: linear-gradient(to bottom, #276136, #4ca363); + } -?> -
    + + +
    + +
    + +
    + +
    +
    @@ -150,7 +153,6 @@ function servercmp($a, $b) {

    (We'll be back up in a few hours.)

    @@ -284,60 +285,94 @@ function servercmp($a, $b) { */ ?>
    +
    + +
    + -

    Links

    - - -

    - @PokemonShowdown on Twitter -

    +
    + + + +

    + @PokemonShowdown on Twitter +

    -
    +
    +
    + + -
    +
    - +
    +

    Servers

    + +
    -

    - -

    - — on -

    +
    +

    + +

    + — on +

    +
    = 2) break; if ($count === 1) { ?> -
    +
    (adsbygoogle = window.adsbygoogle || []).push({}); -
    +
    -

    - Older news » -

    - -
    -
    - - - + Older news » + -includeFooter(); +
    + -?> + diff --git a/website/lib/serverlist.inc.php b/website/lib/serverlist.inc.php new file mode 100644 index 0000000000..0fb0c7fa60 --- /dev/null +++ b/website/lib/serverlist.inc.php @@ -0,0 +1,69 @@ +query("SELECT `serverid`, `date`, `usercount` FROM `ntbb_userstats`"); + $usercount = array(); + $timenow = time(); + while ($row = $psdb->fetch_assoc($query)) { + if (($timenow - $row['date'] / 1000 > 60 * 30) && ($row['serverid'] !== 'showdown')) { + $usercount[$row['serverid']] = false; // inactive server + } else { + $usercount[$row['serverid']] = $row['usercount']; + } + } + $sortorder = 0; + foreach ($PokemonServers as &$server) { + $server['sortorder'] = $sortorder++; + if ($server['id'] === 'showdown') { + $server['uri'] = '//' . $psconfig['routes']['client']; + } else { + $server['uri'] = 'http://' . $server['id'] . '.psim.us'; + } + } + uasort($PokemonServers, 'servercmp'); + ob_start(); + $more = false; + foreach ($PokemonServers as &$server) { + if (!empty($server['hidden'])) continue; + if (!isset($usercount[$server['id']])) continue; + if (($c = $usercount[$server['id']]) === false) continue; + $usersbit = "
    $c user" . ((intval($c) !== 1) ? 's' : '') . " online"; + if (!$c && !$more && $server['id'] !== 'showdown') { + echo ''; this.$el.html(buf); @@ -3538,23 +3538,21 @@ } var buf = ''; - buf += '

    Pick a variant or

    '; + buf += '

    Pick a variant or

    '; buf += '
    '; var formCount = forms.length; for (var i = 0; i < formCount; i++) { var formid = forms[i].substring(baseid.length); var form = (formid ? formid[0].toUpperCase() + formid.slice(1) : ''); - var offset = '-' + (((i - 1) % 7) * spriteSize) + 'px -' + (Math.floor((i - 1) / 7) * spriteSize) + 'px'; - buf += ''; + buf += ''; } + buf += '
    '; buf += '
    '; - var height = Math.ceil(formCount / 7); - var width = Math.ceil(formCount / height); - this.$el.html(buf).css({'max-width': (4 + spriteSize) * width, 'height': 42 + (4 + spriteSize) * height}); + this.$el.html(buf).css({'max-width': (4 + spriteSize) * 7}); }, setForm: function (form) { var species = Dex.species.get(this.curSet.species); diff --git a/js/client-topbar.js b/js/client-topbar.js index 81d77a2078..9d256098fc 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -34,11 +34,11 @@ var status = app.user.get('status'); var color = away ? 'color:#888;' : BattleLog.hashColor(app.user.get('userid')); if (!app.user.loaded) { - buf = ''; + buf = ''; } else if (app.user.get('named')) { buf = ' ' + BattleLog.escapeHTML(name) + ''; } else { - buf = ''; + buf = ''; } buf += ' '; this.$userbar.html(buf); @@ -378,7 +378,7 @@ buf += '

    ' + (muted ? '(muted)' : '') + '

    '; buf += '

    ' + (muted ? '(muted)' : '') + '

    '; buf += '

    ' + (muted ? '(muted)' : '') + '

    '; - buf += '

    '; + buf += '

    '; this.$el.html(buf).css('min-width', 160); }, events: { @@ -478,13 +478,13 @@ var buf = ''; buf += '

    ' + (avatar ? '' : '') + '' + BattleLog.escapeHTML(name) + '

    '; - buf += '

    '; + buf += '

    '; if (app.user.get('named')) { var registered = app.user.get('registered'); if (registered && (registered.userid === app.user.get('userid'))) { - buf += '

    '; + buf += '

    '; } else { - buf += '

    '; + buf += '

    '; } } @@ -492,37 +492,37 @@ buf += '

    Graphics

    '; var theme = Dex.prefs('theme'); var colorSchemeQuerySupported = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').media !== 'not all'; - buf += '

    '; var onePanel = !!Dex.prefs('onepanel'); if ($(window).width() >= 660) { - buf += '

    '; + buf += '

    '; } - buf += '

    '; - buf += '

    '; + buf += '

    '; + buf += '

    '; if (navigator.userAgent.includes(' Chrome/64.')) { - buf += '

    '; + buf += '

    '; } - buf += '

    '; - buf += '

    '; + buf += '

    '; + buf += '

    '; buf += '
    '; buf += '

    Chat

    '; if (Object.keys(settings).length) { - buf += '

    '; - buf += '

    '; + buf += '

    '; + buf += '

    '; } - buf += '

    '; - buf += '

    '; + buf += '

    '; + buf += '

    '; if (window.Notification) { - buf += '

    '; + buf += '

    '; } - buf += '

    '; - buf += '

    '; + buf += '

    '; + buf += '

    '; var curLang = toID(Dex.prefs('serversettings').language) || 'english'; var possibleLanguages = { "Deutsch": 'german', @@ -538,18 +538,18 @@ "简体中文": 'simplifiedchinese', "中文": 'traditionalchinese', }; - buf += '

    '; var tours = Dex.prefs('tournaments') || 'notify'; - buf += '

    '; + buf += '

    '; var timestamps = this.timestamps = (Dex.prefs('timestamps') || {}); - buf += '

    '; - buf += '

    '; - buf += '

    '; + buf += '

    '; + buf += '

    '; + buf += '

    '; if (window.nodewebkit) { buf += '
    '; @@ -560,9 +560,9 @@ buf += '
    '; if (app.user.get('named')) { - buf += '

    '; + buf += '

    '; } else { - buf += '

    '; + buf += '

    '; } this.$el.html(buf).css('min-width', 160); }, @@ -688,18 +688,18 @@ var cur = this.chatformatting = Dex.prefs('chatformatting') || {}; var buf = '

    Usable formatting:

    '; var ctrlPlus = '' + (navigator.platform === 'MacIntel' ? 'Cmd' : 'Ctrl') + ' + '; - buf += '

    **bold** (' + ctrlPlus + 'B)

    '; - buf += '

    __italics__ (' + ctrlPlus + 'I)

    '; - buf += '

    ``code formatting`` (Ctrl + `)

    '; - buf += '

    ~~strikethrough~~

    '; - buf += '

    ^^superscript^^

    '; - buf += '

    \\\\subscript\\\\

    '; - buf += '

    '; - buf += '

    '; - buf += '

    '; - buf += '

    '; - buf += '

    '; - buf += '

    '; + buf += '

    **bold** (' + ctrlPlus + 'B)

    '; + buf += '

    __italics__ (' + ctrlPlus + 'I)

    '; + buf += '

    ``code formatting`` (Ctrl + `)

    '; + buf += '

    ~~strikethrough~~

    '; + buf += '

    ^^superscript^^

    '; + buf += '

    \\\\subscript\\\\

    '; + buf += '

    '; + buf += '

    '; + buf += '

    '; + buf += '

    '; + buf += '

    '; + buf += '

    '; this.$el.html(buf); }, setOption: function (e) { @@ -714,17 +714,17 @@ initialize: function () { var cur = +app.user.get('avatar'); var buf = ''; - buf += '

    Choose an avatar or

    '; + buf += '

    Choose an avatar or

    '; buf += '
    '; for (var i = 1; i <= 293; i++) { if (i === 162 || i === 168) continue; var offset = '-' + (((i - 1) % 16) * 80 + 1) + 'px -' + (Math.floor((i - 1) / 16) * 80 + 1) + 'px'; - buf += ''; + buf += ''; } buf += '
    '; - buf += '

    '; + buf += '

    '; this.$el.html(buf).css('max-width', 780); }, setAvatar: function (avatar) { @@ -794,18 +794,18 @@ buf += '

    Default

    '; buf += '
    '; - buf += ''; + buf += ''; buf += '
    '; buf += '

    Official

    '; buf += '
    '; - buf += ''; - buf += ''; - buf += ''; - buf += ''; - buf += ''; - buf += ''; + buf += ''; + buf += ''; + buf += ''; + buf += ''; + buf += ''; + buf += ''; buf += '
    '; buf += '

    Custom

    '; @@ -813,7 +813,7 @@ buf += '

    '; buf += '

    '; - buf += '

    '; + buf += '

    '; // April Fool's 2016 - background change disabling // buf = '

    Sorry, the background chooser is experiencing technical difficulties. Please try again tomorrow!

    '; @@ -857,8 +857,8 @@ initialize: function (data) { var buf = '
    '; buf += '

    '; - buf += '

    '; - buf += '

    '; + buf += '

    '; + buf += '

    '; this.$el.css('max-width', 485).html(buf); this.$el.html(buf); @@ -905,8 +905,8 @@ if (noRenameGames) { buf += '

    You can\'t change name in the middle of these games:

    '; buf += '
      ' + noRenameGames + '
    '; - buf += '

    '; - buf += '

    '; + buf += '

    '; + buf += '

    '; buf += ''; this.$el.html(buf); return; @@ -919,7 +919,7 @@ if (name) { buf += '

    (Others will be able to see your name change. To change name privately, use "Log out")

    '; } - buf += '

    '; + buf += '

    '; buf += ''; this.$el.html(buf); @@ -962,7 +962,7 @@ buf += '

    '; buf += '

    '; buf += '

    '; - buf += '

    '; + buf += '

    '; this.$el.html(buf); }, submit: function (data) { @@ -1000,7 +1000,7 @@ buf += '

    '; buf += '

    '; buf += '

    '; - buf += '

    '; + buf += '

    '; this.$el.html(buf); }, submit: function (data) { @@ -1073,12 +1073,12 @@ buf += '

    '; } else { buf += '

    '; - buf += '

    '; + buf += '

    '; } buf += '

    or

    '; buf += '

    If this is someone else\'s account:

    '; - buf += '

    '; + buf += '

    '; buf += ''; this.$el.html(buf); diff --git a/js/client.js b/js/client.js index 26147c0471..d369b7f6ae 100644 --- a/js/client.js +++ b/js/client.js @@ -2546,7 +2546,7 @@ function toId() { }, initialize: function (data) { if (!this.type) this.type = 'semimodal'; - this.$el.html('

    ' + (data.htmlMessage || BattleLog.parseMessage(data.message)) + '

    ' + (data.buttons || '') + '

    ').css('max-width', data.maxWidth || 480); + this.$el.html('

    ' + (data.htmlMessage || BattleLog.parseMessage(data.message)) + '

    ' + (data.buttons || '') + '

    ').css('max-width', data.maxWidth || 480); }, dispatchClickButton: function (e) { @@ -2610,7 +2610,7 @@ function toId() { var buf = '
    '; buf += '

    '; - buf += '

    '; + buf += '

    '; buf += '
    '; this.$el.html(buf); @@ -2797,17 +2797,17 @@ function toId() { buf += '

    '; if (userid === app.user.get('userid') || !app.user.get('named')) { - buf += ''; + buf += ''; if (userid === app.user.get('userid')) { - buf += ' '; + buf += ' '; buf += '


    '; - buf += ' '; + buf += ' '; } else { // Guests can't PM themselves - buf += ' '; + buf += ' '; } } else { - buf += ' '; + buf += ' '; } buf += '

    '; @@ -2865,9 +2865,9 @@ function toId() { var ignored = app.ignore[this.userid] ? 'Unignore' : 'Ignore'; var friended = this.data.friended ? 'Remove friend' : 'Add friend'; this.$el.html( - '

    ' + - '

    ' + - '

    ' + + '

    ' + + '

    ' ); }, @@ -2922,18 +2922,18 @@ function toId() { buf += '

    Couldn\'t connect to server!

    '; if (window.wiiu && document.location.protocol === 'https:') { buf += '

    The Wii U does not support secure connections.

    '; - buf += '

    '; + buf += '

    '; } else if (document.location.protocol === 'https:') { - buf += '

    '; + buf += '

    '; } else { - buf += '

    '; + buf += '

    '; } } else if (data.message && data.message !== true) { buf += '

    ' + data.message + '

    '; - buf += '

    '; + buf += '

    '; } else { buf += '

    You have been disconnected – possibly because the server was restarted.

    '; - buf += '

    '; + buf += '

    '; } buf += ''; @@ -2959,7 +2959,7 @@ function toId() { buf += '

    Please copy all the text from the box above and paste it in the box below.

    '; buf += '

    (You should probably set up config/testclient-key.js so you don\'t have to do this every time.)

    '; buf += '

    '; - buf += '

    '; + buf += '

    '; buf += ''; this.$el.html(buf).css('min-width', 500); }, @@ -2977,8 +2977,8 @@ function toId() { initialize: function (data) { var buf = ''; buf = '

    Your replay has been uploaded! It\'s available at:

    '; - buf += '

    https://' + Config.routes.replays + '/' + data.id + '

    '; - buf += '

    '; + buf += '

    https://' + Config.routes.replays + '/' + data.id + '

    '; + buf += '

    '; this.$el.html(buf).css('max-width', 620); }, clickClose: function () { @@ -3033,11 +3033,11 @@ function toId() { '

    This policy is less restrictive than that of many places, so you might see some "borderline" nicknames that might not be accepted elsewhere. You might consider it unfair that they are allowed to keep their nickname. The fact remains that their nickname follows the above rules, and if you were asked to choose a new name, yours does not.

    '; } if (warning) { - buf += '

    You will be able to close this in 5 seconds

    '; + buf += '

    You will be able to close this in 5 seconds

    '; setTimeout(_.bind(this.rulesTimeout, this), 5000); } else { this.type = 'semimodal'; - buf += '

    '; + buf += '

    '; } this.$el.css('max-width', 760).html(buf); }, diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 88c8a2512c..87bf0fe4b6 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -677,9 +677,9 @@ class BattleTooltips { if (zEffect) text += '

    Z-Effect: ' + zEffect + '

    '; if (this.battle.hardcoreMode) { - text += '

    ' + move.shortDesc + '

    '; + text += '

    ' + move.shortDesc + '

    '; } else { - text += '

    '; + text += '

    '; if (move.priority > 1) { text += 'Nearly always moves first (priority +' + move.priority + ').

    '; } else if (move.priority <= -1) { @@ -823,7 +823,7 @@ class BattleTooltips { } if (illusionIndex) { - text += `

    Possible Illusion #${illusionIndex}${levelBuf}

    `; + text += `

    Possible Illusion #${illusionIndex}${levelBuf}

    `; } if (pokemon.fainted) { @@ -904,7 +904,7 @@ class BattleTooltips { if (serverPokemon && !isActive) { // move list - text += `

    `; + text += `

    `; const battlePokemon = clientPokemon || this.battle.findCorrespondingPokemon(pokemon); for (const moveid of serverPokemon.moves) { const move = Dex.moves.get(moveid); @@ -922,7 +922,7 @@ class BattleTooltips { text += '

    '; } else if (!this.battle.hardcoreMode && clientPokemon?.moveTrack.length) { // move list (guessed) - text += `

    `; + text += `

    `; for (const row of clientPokemon.moveTrack) { text += `${this.getPPUseText(row)}
    `; } @@ -952,7 +952,7 @@ class BattleTooltips { for (const side of this.battle.sides) { const sideConditions = scene.sideConditionsLeft(side, true); if (sideConditions) atLeastOne = true; - buf += `

    ${BattleLog.escapeHTML(side.name)}${sideConditions || "
    (no conditions)"}

    `; + buf += `

    ${BattleLog.escapeHTML(side.name)}${sideConditions || "
    (no conditions)"}

    `; } buf += ``; if (!atLeastOne) buf = ``; diff --git a/src/panel-topbar.tsx b/src/panel-topbar.tsx index deb456452f..7a10fa7dfb 100644 --- a/src/panel-topbar.tsx +++ b/src/panel-topbar.tsx @@ -203,10 +203,10 @@ class PSHeader extends preact.Component<{style: {}}> { } renderUser() { if (!PS.connected) { - return ; + return ; } if (!PS.user.userid) { - return ; + return ; } if (!PS.user.named) { return Choose name; @@ -366,8 +366,8 @@ class UserPanel extends PSRoomPanel { {isSelf || !PS.user.named ?

    - {} - + {} +

    :

    diff --git a/style/STYLING.html b/style/STYLING.html index 4aa0fe052b..348377bbd1 100644 --- a/style/STYLING.html +++ b/style/STYLING.html @@ -111,7 +111,7 @@

    Buttons and links

    .button.disabled

    - Disabled buttons are faded out. Implementing disabled as a class lets you detect when they're moused-over (for tooltips) and clicked, if necessary. Do also set the disabled attribute if you don't need to do that, though, for accessibility reasons. + Disabled buttons are faded out. Implementing disabled as a class lets you detect when they're moused-over (for tooltips) and clicked, if necessary. Do instead set the disabled attribute if you don't need to do that, though, for accessibility reasons.

    @@ -211,21 +211,21 @@

    Forms

    This is used for a button taking the role of <option> (in a drop-down selection menu). Normal button styling would look really cluttered, so option buttons are much subtler.

    - The currently-selected option should be given the sel class. + The currently-selected option should be given the cur class.

    - +
    - +
    - <button class="option sel">Do the first thing</button> + <button class="option cur">Do the first thing</button> <button class="option">Do the second thing</button> <button class="option">Do the third thing</button>
    diff --git a/style/battle-log.css b/style/battle-log.css index 1050fed8e4..d6c47997f9 100644 --- a/style/battle-log.css +++ b/style/battle-log.css @@ -39,7 +39,7 @@ .dark .blocklink { box-shadow: none; text-shadow: none; - border-color: #7799BB; + border-color: #526c87; background: rgba(30, 40, 50, .5); color: #7799BB; } @@ -58,7 +58,6 @@ button, summary { touch-action: manipulation; } .button { - outline: none; cursor: pointer; text-align: center; text-decoration: none; @@ -75,23 +74,29 @@ button, summary { text-shadow: 0 1px 0 white; border: 1px solid #AAAAAA; background: #e3e3e3; - background: linear-gradient(to bottom, #f6f6f6, #e3e3e3); + background: linear-gradient(to bottom, #f6f6f6, #d3d3d3); font-size: 9pt; padding: 3px 8px; } +select.button { + text-align: left; +} .button:hover { background: #cfcfcf; - background: linear-gradient(to bottom, #f2f2f2, #c2c2c2); + background: linear-gradient(to bottom, #f2f2f2, #b2b2b2); border-color: #606060; } .button:active { - background: linear-gradient(to bottom, #cfcfcf, #f2f2f2); + background: linear-gradient(to bottom, #bfbfbf, #f2f2f2); } .button.disabled, .button.disabled:hover, -.button.disabled:active { +.button.disabled:active, +.button:disabled, +.button:disabled:hover, +.button:disabled:active { cursor: default; background: #EEEEEE; border: 1px solid #CCCCCC; @@ -104,31 +109,117 @@ button:disabled { cursor: default; } +.button.notifying { + border-color: #AA8866; + background: #e3c3a3; + background: linear-gradient(to bottom, #f6d6b6, #d3b396); +} +.button.notifying:hover { + border-color: #604020; + background: #cfaf8f; + background: linear-gradient(to bottom, #f2c6a6, #b28e6e); +} +.button.notifying:active { + background: #b28e6e; + background: linear-gradient(to bottom, #b28e6e, #f6d6b6); +} +.button.alt-notifying { + border-color: #669caa; + background: #a3d0e3; + background: linear-gradient(to bottom, #daf2fc, #a3d0e3); +} +.button.alt-notifying:hover { + border-color: #406070; + background: #8fb2cf; + background: linear-gradient(to bottom, #daf2fc, #8fb2cf); +} +.button.alt-notifying:active { + background: #8fb2cf; + background: linear-gradient(to bottom, #8fb2cf, #daf2fc); +} +.button.subtle-notifying { + color: #AA6600; +} + +.button-first, .button-middle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.button-last, .button-middle { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; +} +.button-first:hover, .button-middle:hover { + /* puts the right-border over the left border of the button to the right of it */ + position: relative; +} + .dark .button { - background: #484848; - box-shadow: inset 0 3px 4px rgba(255, 255, 255, 0.25); - border-color: #A9A9A9; + background: #2b2c31; + background: linear-gradient(to bottom, #4e525a, #2b2c31); + box-shadow: 0.5px 1px 2px rgba(255, 255, 255, 0.45), inset 0.5px 1px 1px rgba(255, 255, 255, 0.5); + border-color: #34373b; text-shadow: none; color: #F9F9F9; } .dark .button:hover { - background: #606060; - border-color: #EEEEEE; + background: #3e4149; + background: linear-gradient(to bottom, #646877, #3e4149); + border-color: #50555b } .dark .button:active { - background: #3A3A3A; - border-color: #EEEEEE; + background: #2b2c31; + background: linear-gradient(to bottom, #2b2c31, #4e525a); + border-color: #34373b; box-shadow: none; } .dark .button.disabled, .dark .button.disabled:hover, -.dark .button.disabled:active { +.dark .button.disabled:active, +.dark .button:disabled, +.dark .button:disabled:hover, +.dark .button:disabled:active { background: #555555; - border-color: #555555; - box-shadow: none; + border-color: #34373b; + box-shadow: 0.5px 1px 2px rgba(255, 255, 255, 0.45); color: #999999; } +.dark .button.notifying { + border-color: #34373b; + background: #417589; + background: linear-gradient(to bottom, #449cbf, #2b6d87); +} +.dark .button.notifying:hover { + border-color: #34373b; + background: #5499b4; + background: linear-gradient(to bottom, #4fb7df, #398bac); +} +.dark .button.notifying:active { + border-color: #34373b; + background: #5499b4; + background: linear-gradient(to bottom, #2b6d87, #4ebde9); +} +.dark .button.alt-notifying { + border-color: #34373b; + background: #502646; + background: linear-gradient(to bottom, #713262, #502646); +} +.dark .button.alt-notifying:hover { + border-color: #34373b; + background: #713563; + background: linear-gradient(to bottom, #9f468b, #713563); +} +.dark .button.alt-notifying:active { + border-color: #34373b; + background: #713563; + background: linear-gradient(to bottom, #502646, #9f468b); +} +.dark .button.subtle-notifying { + color: #72bcda; +} + /********************************************************* * Forms *********************************************************/ @@ -203,8 +294,7 @@ button:disabled { box-shadow: inset 0px 1px 2px #D2D2D2, 1px 1px 0 rgba(255,255,255,.6); background: #FFFFFF; } -.textbox:focus, -.button:focus { +.textbox:focus { outline: 0 none; border-color: #004488; box-shadow: inset 0px 1px 2px #D2D2D2, 0px 0px 6px #2266AA; @@ -217,30 +307,36 @@ button:disabled { color: #555555; } .dark .textbox { - border-color: #888888; + border-color: #6b7178; - box-shadow: inset 0px -1px 2px #606060, -1px -1px 0 rgba(255,255,255,.2); - background: #282B2D; + /* box-shadow: inset 0px -1px 2px #606060, -1px -1px 0 rgba(255,255,255,.2); */ + box-shadow: inset 0.5px 1px 2px rgba(0, 0, 0, 1), inset -0.5px -1px 1px rgba(255, 255, 255, 0.2), -0.5px -1px 1px rgba(255, 255, 255, 0.1); + background: #222527; color: #DDD; } .dark .textbox:hover { - border-color: #BBBBBB; - box-shadow: inset 0px -1px 2px #606060, -1px -1px 0 rgba(255,255,255,.2); - background: #222222; + border-color: #8d959f; + box-shadow: inset 0.5px 1px 2px rgba(0, 0, 0, 0.8), inset -0.5px -1px 1px rgba(255, 255, 255, 0.5), -0.5px -1px 1px rgba(255, 255, 255, 0.1); + background: #111111; } -.dark .textbox:focus, -.dark .button:focus { - outline: 0 none; - border-color: #BBBBBB; - box-shadow: 0px 0px 4px #88CCFF, 0px 0px 6px #88CCFF; +.dark .textbox:focus { + outline: 1px solid #6295bc; + border-color: #9199a2; + /* box-shadow: 0px 0px 4px #88CCFF, 0px 0px 6px #88CCFF; */ } .dark .textbox:focus { background: #111111; - box-shadow: inset 0px -1px 2px #606060, 0px 0px 4px #88CCFF, 0px 0px 6px #88CCFF; + /* box-shadow: inset 0.5px 1px 2px rgba(0, 0, 0, 0.8), inset -0.5px -1px 1px rgba(255, 255, 255, 0.5), 0px 0px 4px #88CCFF, 0px 0px 6px #88CCFF; */ +} +.dark .textbox.disabled, .dark .textbox:disabled { + opacity: 0.7; + color: #AAA; + border-color: #444; + box-shadow: none; } .option { - background: transparent; + background-color: transparent; border: 1px solid transparent; border-radius: 4px; padding: 2px 5px; @@ -251,13 +347,14 @@ button:disabled { white-space: nowrap; overflow: hidden; } -.option.sel { +.option.sel, .option.cur { border-color: #999999; } .option:hover, -.option.sel:hover { +.option.sel:hover, +.option.cur:hover { border-color: #888888; - background: #D5D5D5; + background-color: #D5D5D5; color: black; } @@ -266,9 +363,10 @@ button:disabled { box-shadow: none; } .dark .option:hover, -.dark .option.sel:hover { +.dark .option.sel:hover, +.dark .option.cur:hover { border-color: #777777; - background: rgba(100, 100, 100, 0.5); + background-color: rgba(100, 100, 100, 0.5); color: #FFFFFF; } @@ -279,6 +377,10 @@ hr { border-right: 0; } +.dark hr { + border-color: #707070; +} + select { font-size: 9pt; font-family: Verdana, Helvetica, Arial, sans-serif; @@ -338,6 +440,50 @@ input[type=range]:active::-webkit-slider-thumb { box-shadow: inset 0px 1px 1px #DDD; } +/** stolen from devdocs.io */ +.dark:not(.native-scrollbars) *::-webkit-scrollbar { + -webkit-appearance: none +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar:vertical { + width: 16px +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar:horizontal { + height: 16px +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar-button,.dark:not(.native-scrollbars) *::-webkit-scrollbar-corner { + display: none +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar-track { + background: transparent; + border: 1px solid transparent; +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar-track:hover { + background: #24282a; + border-color: #000000; +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar-track:vertical { + border-width: 0 0 0 1px; +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar-track:vertical:corner-present { + border-width: 0 0 1px 1px; + border-radius: 0 0 0 2px; +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar-track:horizontal { + border-width: 1px 1px 0 1px; + border-radius: 2px 2px 0 0; +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar-thumb { + min-height: 2rem; + background: #6c6c6f; + background-clip: padding-box; + border: 5px solid transparent; + border-radius: 10px; +} +.dark:not(.native-scrollbars) *::-webkit-scrollbar-thumb:hover,.dark:not(.native-scrollbars) *::-webkit-scrollbar-thumb:active { + background-color: #949697; + border-width: 4px; +} + /********************************************************* * Everything else *********************************************************/ @@ -353,6 +499,7 @@ input[type=range]:active::-webkit-slider-thumb { } .dark .message-log h2 { background: #555555; + border-color: #5A5A5A; } .chat, .notice { vertical-align: middle; @@ -368,6 +515,9 @@ input[type=range]:active::-webkit-slider-thumb { .chat > strong { /* username, changed rating */ color: #40576A; } +.dark .username { + filter: brightness(1.2); +} .chat > em, .chat > q { /* user's chat message */ padding: 0 4px 0 3px; @@ -442,7 +592,7 @@ input[type=range]:active::-webkit-slider-thumb { background: #BBBBBB; color: #BBBBBB; } -code, .code, +code, .code, kbd, .spoiler:hover code, .spoiler:active code, .spoiler-shown code { @@ -453,6 +603,13 @@ code, .code, padding: 0 2px; tab-size: 4; } +kbd { + font-size: 90%; + padding: 0 4px; + border-radius: 4px; + border-width: 1px 3px 3px; + border-color: #CCC #BBB #AAA; +} details.readmore { position: relative; @@ -497,8 +654,7 @@ details.readmore[open] summary:hover:before { background: #777; color: #777; } -.dark code, -.dark .code, +.dark code, .dark .code, .dark kbd, .dark .spoiler:hover code, .dark .spoiler:active code, .dark .spoiler-shown code { @@ -506,6 +662,10 @@ details.readmore[open] summary:hover:before { background: #333; color: #DDD; } +.dark kbd { + background: #555; + border-color: #666 #333 #111; +} .stat-boosted { color: #117911; } @@ -542,29 +702,30 @@ details.readmore[open] summary:hover:before { /* Readable link colour */ color: #DDEEFF; } -.broadcast-green { +.broadcast-green, .broadcast-blue, .broadcast-red { background-color: #559955; color: white; padding: 2px 4px; + border-radius: 4px; } .broadcast-blue { background-color: #6688AA; - color: white; - padding: 2px 4px; +} +.broadcast-red { + background-color: #AA5544; } .infobox { - border: 1px solid #6688AA; + border: 1px solid #7799BB; padding: 2px 4px; + border-radius: 4px; +} +.dark .infobox { + border-color: #506070; } .infobox-limited { max-height: 200px; overflow: auto; } -.broadcast-red { - background-color: #AA5544; - color: white; - padding: 2px 4px; -} .message-learn-canlearn { font-weight: bold; color: #228822; diff --git a/style/battle.css b/style/battle.css index 81a20d86a1..ded33430ea 100644 --- a/style/battle.css +++ b/style/battle.css @@ -5,7 +5,7 @@ License: GPLv2 */ -@import url(./battle-log.css?v4); +@import url(./battle-log.css?v6); .battle { position: absolute; @@ -75,6 +75,9 @@ License: GPLv2 overflow-scrolling: touch; word-wrap: break-word; } +.dark .battle, .dark .battle-log, .dark .battle-log-add { + border-color: #5A5A5A; +} .battle-log-inline { position: static; top: auto; @@ -787,7 +790,7 @@ License: GPLv2 #tooltipwrapper .tooltip p small { font-size: 8pt; } -#tooltipwrapper .tooltip p.section { +#tooltipwrapper .tooltip p.tooltip-section { border-top: 1px solid #888888; } #tooltipwrapper .tooltip .textaligned-typeicons img { diff --git a/style/client.css b/style/client.css index 08ec18629d..68fcbe1fd2 100644 --- a/style/client.css +++ b/style/client.css @@ -28,235 +28,42 @@ body { .pad p { margin: 9px 0; } -.label { - font-size: 9pt; - font-weight: bold; - display: block; -} -.optlabel { - font-size: 9pt; - display: block; -} .label strong { font-size: 11pt; display: block; } -.label .textbox { - display: block; -} -.textbox { - border: 1px solid #AAAAAA; - border-radius: 3px; - padding: 2px 3px; - font-family: Verdana, Helvetica, Arial, sans-serif; - font-size: 9pt; - - box-shadow: inset 0px 1px 2px #CCCCCC, 1px 1px 0 rgba(255,255,255,.6); - background: #F8FBFD; - color: black; -} -.textbox:hover { - border-color: #474747; - box-shadow: inset 0px 1px 2px #D2D2D2, 1px 1px 0 rgba(255,255,255,.6); - background: #FFFFFF; -} -.textbox:focus, -.button:focus { - outline: 0 none; - border-color: #004488; - box-shadow: inset 0px 1px 2px #D2D2D2, 0px 0px 5px #2266AA; -} -.textbox:focus { - background: #FFFFFF; -} -.textbox.disabled, .textbox:disabled { - background: #CCCCCC; - color: #555555; -} .buttonbar { margin-top: 1em; text-align: center; } -hr { - border-top: 1px solid #999999; - border-bottom: 0; - border-left: 0; - border-right: 0; -} - select { font-size: 9pt; font-family: Verdana, Helvetica, Arial, sans-serif; } -/* .dark a.button { - color: #222222; - text-shadow: 0 1px 0 white; - border: solid 1px #AAAAAA; - background: #e3e3e3; - background: linear-gradient(to bottom, #f6f6f6, #e3e3e3); -} -.dark a.button:hover { - background: #cfcfcf; - background: linear-gradient(to bottom, #f2f2f2, #c2c2c2); - border-color: #606060; -} -.dark a.button:active { - background: linear-gradient(to bottom, #cfcfcf, #f2f2f2); -} */ - -.dark .button.notifying { - background: #6BACC5; - border-color: #2C9CC1; -} - -.dark .button.notifying.subtle { - border-color: #000000; - background: #b2d7f7; - color: black; -} - -.dark .button.notifying:hover { - background: #6BACC5; - border-color: #FFFFFF; -} - -.dark a.button:visited { - color: #F9F9F9; -} -.dark a.button.subtle-notifying { - color: #61A3BB; -} - -.dark .textbox { - border-color: #888888; - - box-shadow: none; - background: #282B2D; - color: #DDD; +.dark .tabbar a.button { + box-shadow: inset 0.5px 1px 1px rgba(255, 255, 255, 0.5); } -.dark .textbox:hover { - border-color: #BBBBBB; +.dark .tabbar a.button:active, +.dark .tabbar a.button.cur:active { box-shadow: none; - background: #222222; -} -.dark .textbox:focus, -.dark .button:focus { - outline: 0 none; - border-color: #BBBBBB; - box-shadow: 0px 0px 4px #88CCFF, 0px 0px 4px #88CCFF; -} -.dark .textbox:focus { - background: #111111; -} -/* .dark .roomtab.button.closable, -.dark .roomtab.button { - background: #3A3A3A; - border-color: #A9A9A9; - color: #F9F9F9; - text-shadow: 1px 1px 0 #111; -} -.dark .roomtab.button:hover { - background: #606060; - border-color: #EEEEEE; -} -.dark .roomtab.button.cur.closable, -.dark .roomtab.button.cur { - background: #636363; - border-color: #A9A9A9; - color: #F9F9F9; - text-shadow: 1px 1px 0 #111; -} */ -.dark .tabbar a.button.subtle-notifying { - color: #6BACC5; -} -.dark .tabbar a.button.notifying { - background: #6BACC5; - border-color: #2C9CC1; - color: #000; - text-shadow: none; } .dark .maintabbarbottom { - background: #636363; - border-color: #A9A9A9; -} - -/* .dark button { - background: #777777; - box-shadow: none; - border: 1px solid #EEEEEE; - color: #EEEEEE; - border-radius: 5px; -} -*/ -.dark .folderButton, -.dark .tabbar a.button, -.dark .popupmenu .folderButton, -.dark .popupmenu .folderButtonOpen, -.dark .popupmenu button.button { - background: #484848; - box-shadow: inset 0 3px 4px rgba(255, 255, 255, 0.25); - border-color: #A9A9A9; - text-shadow: none; - color: #F9F9F9; -} - -.dark .popupmenu button.folderButtonOver { - background: linear-gradient(to bottom, #2a2a2a, #313131); -} - -.dark .popupmenu button.folderButtonOpen:hover { - color: #F9F9F9; -} - -.dark .popupmenu button.folderButtonOpen:hover, -.dark .folderButton:hover, -.dark .popupmenu button.folderButton:hover, -.dark .popupmenu button.button:hover, -.dark .tabbar a.button:hover { - background: #606060; - border-color: #EEEEEE; -} - -.dark .folderButton:hover, -.dark .popupmenu button.folderButton:hover, -.dark .popupmenu button.button:hover { - color: #F9F9F9; + background: #555555; + border-color: #5A5A5A; + border-top-color: #34373b; } -.dark .tabbar a.button.notifying:hover { - background: #92C2D3; -} -.dark .tabbar a.button:active { - background: #3A3A3A; - border-color: #EEEEEE; - box-shadow: none; -} .dark .button.cur, .dark .button.cur:hover, .dark .tabbar a.button.cur, .dark .tabbar a.button.cur:hover { - background: #636363; - border-color: #A9A9A9; - box-shadow: none; - color: #F9F9F9; -} -.dark .button.disabled, -.dark .button.disabled:hover, -.dark .button.disabled:active { background: #555555; - border-color: #555555; + border-color: #34373b; box-shadow: none; - color: #999999; + color: #F9F9F9; } -/* -.dark .closebutton, -.dark .minimizebutton, -.dark button.subtle { - background: none; - border: none; -} */ /********************************************************* * Header @@ -314,7 +121,7 @@ select { display: block; list-style: none; margin: 0; - padding: 0 0 0 0; + padding: 2px 0 0 0; height: 37px; text-align: left; @@ -335,6 +142,7 @@ select { background: #f8f8f8; border: solid 1px #AAAAAA; border-left: 0; + border-right: 0; margin: -1px 0 0 0; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2); -moz-box-shadow: 0 1px 2px rgba(0,0,0,.2); @@ -365,63 +173,15 @@ select { border-radius: 0; } -.popupmenu button.button { - outline: none; - cursor: pointer; - text-align: center; - text-decoration: none; - border-radius: 5px; - -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2), inset 0 -1px 2px rgba(255,255,255,1); - -moz-box-shadow: 0 1px 2px rgba(0,0,0,.2), inset 0 -1px 2px rgba(255,255,255,1); - box-shadow: 0 1px 2px rgba(0,0,0,.2), inset 0 -1px 2px rgba(255,255,255,1); - border-radius: 5px; - font-family: Verdana, Helvetica, Arial, sans-serif; - display: inline-block; - - /* default colors */ - color: #222222; - text-shadow: 0 1px 0 white; - border: solid 1px #AAAAAA; - background: #e3e3e3; - background: linear-gradient(to bottom, #f6f6f6, #e3e3e3); - - font-size: 9pt; - padding: 3px 8px; +.popupmenu .option { + width: 204px; } - .popupmenu i { display: inline-block; width: 16px; color: #777777; } -.popupmenu button.folderButton, -.popupmenu button.folderButtonOpen { - width: 172px; - outline: none; - cursor: pointer; - text-decoration: none; - border-radius: 5px; - -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2), inset 0 -1px 2px rgba(255,255,255,1); - -moz-box-shadow: 0 1px 2px rgba(0,0,0,.2), inset 0 -1px 2px rgba(255,255,255,1); - box-shadow: 0 1px 2px rgba(0,0,0,.2), inset 0 -1px 2px rgba(255,255,255,1); - border-radius: 5px; - font-family: Verdana, Helvetica, Arial, sans-serif; - display: inline-block; - /* default colors */ - color: #222222; - text-shadow: 0 1px 0 white; - border: solid 1px #AAAAAA; - background: #e3e3e3; - background: linear-gradient(to bottom, #f6f6f6, #e3e3e3); - font-size: 9pt; - padding: 3px 8px; -} - -.popupmenu button.folderButtonOpen { - background: linear-gradient(to bottom, #e4e4e4, #d3d3d3); -} - .button.small, .button.small { font-size: 8pt; @@ -432,16 +192,6 @@ select { font-size: 12pt; padding: 5px 10px; } -.popupmenu button.folderButton:hover, -.popupmenu button.folderButtonOpen:hover, -.popupmenu button.button:hover { - background: #cfcfcf; - background: linear-gradient(to bottom, #f2f2f2, #c2c2c2); - border-color: #606060; -} -.popupmenu button.button:active { - background: linear-gradient(to bottom, #cfcfcf, #f2f2f2); -} .mainmenuwrapper .menugroup .button.disabled, .mainmenuwrapper .menugroup .button.disabled:hover, @@ -456,31 +206,14 @@ select { box-shadow: 0 1px 2px rgba(0,0,0,.1); } -.button.notifying { - border-color: #AA8866; - background: #e3c3a3; -} -.button.notifying:hover { - border-color: #604020; - background: #cfaf8f; -} -.button.notifying.subtle { - border-color: #000000; - background: #b2d7f7; - color: black; -} .button.cur, -.folderButton.cur, .button.cur:hover { - color: #777777; + color: #333333; background: #f8f8f8; box-shadow: none; border-color: #AAAAAA; cursor: default; } -.button.subtle-notifying { - color: #AA6600; -} .button.subtle-notifying .fa-comment-o:before, .button.notifying .fa-comment-o:before { content: "\f0e6"; @@ -496,7 +229,6 @@ i.subtle:hover { filter: alpha(opacity=100); } - .tabbar li, .tabbar ul { display: block; @@ -517,9 +249,12 @@ i.subtle:hover { margin: 0 -1px 0 0; top: 1px; border-radius: 0; - box-shadow: none; + box-shadow: inset 0 -1px 2px rgba(255,255,255,1); font-size: 11px; } +.tabbar a.button.cur { + box-shadow: none; +} .tabbar a.button i { display: block; text-align: center; @@ -543,7 +278,9 @@ i.subtle:hover { margin-right: -6px; } .tabbar a.button:hover, -.tablist a.button:hover { +.tablist a.button:hover, +.tabbar a.button:focus, +.tablist a.button:focus { z-index: 10; } .tabbar a.button.cur, @@ -592,6 +329,9 @@ i.subtle:hover { .closebutton:hover { color: #BB2222; } +.dark .closebutton:hover { + color: #EE7777; +} span.header-username:hover { color: #333333; } @@ -599,6 +339,10 @@ span.header-username:hover { .pm-window h3:hover .minimizebutton { color: #333333; } +.dark .minimizebutton:hover, +.dark .pm-window h3:hover .minimizebutton { + color: #CCCCCC; +} .pm-window h3 .closebutton:hover + .minimizebutton { color: #999999 !important; } @@ -610,10 +354,12 @@ span.header-username:hover { color: #661111; } .pm-minimized .minimizebutton .fa-minus-circle:before { + /** replace the minus with a plus when PM is minimized */ content: "\f055"; } .tablist li, .tablist ul { + /** tablist is the menu that's displayed when the window is too wide for all the tabs */ list-style: none; margin: 0; padding: 0; @@ -691,7 +437,6 @@ span.header-username:hover { .scrollable { overflow: auto; -webkit-overflow-scrolling: touch; - overflow-scrolling: touch; } .ps-room.ps-room-light { background: rgba(242,247,250,.85); @@ -713,7 +458,6 @@ span.header-username:hover { overflow: auto; -webkit-overflow-scrolling: touch; - overflow-scrolling: touch; z-index: 20; } .ps-popup { @@ -734,7 +478,9 @@ span.header-username:hover { margin: 80px auto 20px auto; max-width: 320px; } -.ps-popup p, +.ps-popup p { + margin: 4px 0; +} .ps-popup h3 { margin: 7px 0; } @@ -782,21 +528,6 @@ p.or:after { .popupmenu li:first-child h3 { margin-top: 0; } -.popupmenu button { - display: block; - font-size: 8pt; - font-family: Verdana, Helvetica, Arial, sans-serif; - margin: 0 0 0 6px; - padding: 2px 3px; - border: 1px solid transparent; - border-radius: 2px; - background: transparent; - color: black; - width: 204px; - text-align: left; - - box-sizing: border-box; -} @media (max-height:590px) { .popupmenu h3 { margin-top: 2px; @@ -811,18 +542,7 @@ p.or:after { } } -.popupmenu button.sel { - border-color: #AAAAAA; - white-space: nowrap; - overflow: hidden; -} -.popupmenu button:hover, -.popupmenu button.sel:hover { - border-color: #888888; - background: #D5D5D5; - color: black; -} -.popupmenu button.button { +.popupmenu .button { margin: 2px auto 5px; width: 184px; } @@ -1001,14 +721,21 @@ p.or:after { border-color: #AA8866; background: #E3C3A3; } +.dark .pm-window h3.pm-notifying { + background: #417589; + color: #BBBBBB; +} .pm-window h3.pm-notifying:hover { border-color: #604020; background: #CFAF8F; } +.dark .pm-window h3.pm-notifying:hover { + background: #417589; +} .pm-window h3 .closebutton, .pm-window h3 .minimizebutton { float: right; - margin: -3px -3px; + margin: -2px -3px; width: 22px; height: 22px; } @@ -1028,7 +755,6 @@ p.or:after { overflow: auto; -webkit-overflow-scrolling: touch; - overflow-scrolling: touch; word-wrap: break-word; } .pm-buttonbar { @@ -1055,6 +781,18 @@ p.or:after { background: #f8f8f8; color: #222222; } +.dark .pm-window h3 { + background: rgba(50,50,50,.8); + color: #AAA; +} +.dark .pm-window h3:hover { + color: #CCC; +} +.dark .pm-window.focused h3, +.dark .pm-window.focused h3:hover { + background: #222; + color: #EEE; +} .challenge { margin-top: -1px; background: #fcd2b3; @@ -1298,32 +1036,6 @@ p.or:after { max-width: 480px; text-align: left; } -.roomlist a.ilink { - display: block; - margin: 2px 7px 4px 7px; - padding: 1px 4px 2px 4px; - border: 1px solid #BBCCDD; - background: rgba(248, 251, 253, 0.5); - - border-radius: 4px; - text-decoration: none; - color: #336699; - text-shadow: #ffffff 0px -1px 0; - cursor: pointer; - font-size: 10pt; - - overflow: hidden; - white-space: nowrap; -} -.roomlist a.ilink small { - font-size: 8pt; -} -.roomlist a.ilink:hover { - border-color: #778899; - background: #E5EAED; - color: #224466; - text-decoration: none; -} .roomlist .subrooms { font-size: 8pt; padding-left: 20px; @@ -1332,7 +1044,7 @@ p.or:after { .roomlist .subrooms i.fa-level-up { margin-right: 5px; } -.roomlist .subrooms a.ilink { +.roomlist .subrooms a.blocklink { display: inline-block; margin: 0; vertical-align: middle; @@ -1356,7 +1068,6 @@ p.or:after { overflow: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; - overflow-scrolling: touch; word-wrap: break-word; } .chat-log-add { @@ -1729,7 +1440,6 @@ a.ilink.yours { overflow: auto; -webkit-overflow-scrolling: touch; - overflow-scrolling: touch; } .pm-buttonbar { height: 21px; @@ -1744,6 +1454,9 @@ a.ilink.yours { border-right: 1px solid #AAAAAA; border-bottom: 1px solid #AAAAAA; } +.dark .userlist, .dark .pm-buttonbar button, .dark .chat-log-add, .dark .pm-window h3, .dark .pm-log, .dark .newsentry { + border-color: #5A5A5A; +} .userlist-minimized { height: 21px; bottom: auto; @@ -1780,8 +1493,7 @@ a.ilink.yours { text-align: left; } .userlist li { - border-bottom: 1px solid #CCCCCC; - height: 19px; + height: 20px; font: 10pt Verdana, sans-serif; white-space: nowrap; } @@ -1804,7 +1516,7 @@ a.ilink.yours { border: 0; padding: 1px 0; margin: 0; - height: 19px; + height: 20px; width: 100%; white-space: nowrap; font: 9pt Verdana, sans-serif; @@ -2869,8 +2581,6 @@ a.ilink.yours { color: #CC3311; border-color: #CC3311; } -.setchart-nickname input { -} .setchart .setcell-details input { width: 216px; } @@ -2994,7 +2704,6 @@ a.ilink.yours { overflow-y: scroll; -webkit-overflow-scrolling: touch; - overflow-scrolling: touch; } @media (max-height:410px) { .teambuilder-results { @@ -3031,7 +2740,6 @@ a.ilink.yours { overflow: auto; -webkit-overflow-scrolling: touch; - overflow-scrolling: touch; } .teamwrapper.scaled { width: 640px; @@ -3254,11 +2962,6 @@ a.ilink.yours { float: left; margin: 2px; padding: 2px; - - border: 1px solid transparent; - border-radius: 4px; - box-shadow: none; - background: transparent; } .avatarlist button { width: 80px; @@ -3271,20 +2974,8 @@ a.ilink.yours { height: 90px; background: url(../fx/client-bgsheet.png) no-repeat scroll 0px 0px; } -.avatarlist button.cur, -.formlist button.cur, -.bglist button.cur { - border-color: #999999; -} -.avatarlist button:hover, -.avatarlist button.cur:hover, -.formlist button:hover, -.formlist button.cur:hover, -.bglist button:hover, -.bglist button.cur:hover { - border: 1px solid #8899AA; - background-color: #F1F4F9; - box-shadow: 1px 1px 1px #D5D5D5; +.formlist button { + background-repeat: no-repeat; } .effect-volume, @@ -3325,11 +3016,13 @@ a.ilink.yours { .dark .pm-log-add { background: rgba(0,0,0,.70); color: #DDD; + border-color: #5A5A5A; } .dark .pm-log { background: rgba(0,0,0,.85); color: #DDD; + backdrop-filter: blur(4px); } .dark .userlist-maximized { @@ -3366,6 +3059,7 @@ a.ilink.yours { .dark .chat-log { background: rgba(0,0,0,.5); color: #DDD; + backdrop-filter: blur(4px); } .dark .userbar .username { @@ -3378,29 +3072,15 @@ a.ilink.yours { .dark .ps-popup { background: #0D151E; color: #DDD; - border-color: #888; + border-color: #34373b; - box-shadow: 2px 2px 3px rgba(0,0,0,.2); + box-shadow: 2px 2px 3px rgba(0,0,0,.5), inset 0.5px 1px 1px rgba(255, 255, 255, 0.5); } .dark .usergroup { color: #BBB; } -.dark .popupmenu button, -.dark .bglist button, -.dark .avatarlist button { - color: #AAA; - box-shadow: none; -} -.dark .popupmenu button:hover, -.dark .popupmenu button.sel:hover, -.dark .bglist button:hover, -.dark .avatarlist button:hover { - border-color: #AAAAAA; - background-color: #AAAAAA; - color: black; -} .dark .changeform i { border-color: #bbb; color: #bbb; @@ -3482,6 +3162,7 @@ a.ilink.yours { } .dark a.ilink { color: #4488EE; + border-color: #526c87; } .dark .chat.mine { background: rgba(255,255,255,0.05); @@ -3602,50 +3283,9 @@ a.ilink.yours { color: #BBB; } -/* rooms */ -.dark .roomlist a.ilink { - box-shadow: none; - text-shadow: none; -} - -.dark .roomlist a.ilink { - border-color: #7799BB; - background: rgba(30, 40, 50, .5); - color: #7799BB; -} -.dark .roomlist a.ilink:hover { - border-color: #AACCEE; - background: rgba(30, 40, 50, 1); - color: #AACCEE; -} - -/* misc */ +/* for testclient */ .dark iframe.textbox, .dark iframe.textbox:hover, .dark iframe.textbox:focus { background: #DDDDDD; } - -/********************************************************* - * - *********************************************************/ - -@-webkit-keyframes blinker { - from { opacity: 1.0; } - to { opacity: 0.0; } -} -@keyframes blinker { - from { opacity: 1.0; } - to { opacity: 0.0; } -} -blink { - -webkit-animation-name: blinker; - -webkit-animation-iteration-count: infinite; - -webkit-animation-timing-function: cubic-bezier(1.0,0,0,1.0); - -webkit-animation-duration: 1s; - animation-name: blinker; - animation-iteration-count: infinite; - animation-timing-function: cubic-bezier(1.0,0,0,1.0); - animation-duration: 1s; - text-decoration: none; -} From f9bc940eb5b2f2d55f7ea9b5c8c82e9ffe62c3c0 Mon Sep 17 00:00:00 2001 From: LumarisX <65790297+LumarisX@users.noreply.github.com> Date: Sat, 4 Nov 2023 00:04:15 -0700 Subject: [PATCH 533/770] Give JSON files the Access-Control-Allow-Origin: * header (#2172) --- .htaccess | 1 + 1 file changed, 1 insertion(+) diff --git a/.htaccess b/.htaccess index 6bedf899f9..bea8fe2d1d 100644 --- a/.htaccess +++ b/.htaccess @@ -91,6 +91,7 @@ RewriteCond %{HTTP_HOST} ^www\.play\.pokemonshowdown\.com$ [NC] RewriteRule ^(.*) https://play.pokemonshowdown.com/$1 [R=301,L] RewriteRule ^style/fonts?/.*?\.(eot|svg|ttf|woff|woff2)$ - [E=SAFE_RESOURCE:1] +RewriteRule ^data/(moves|abilities|learnsets).json$ - [E=SAFE_RESOURCE:1] Header set Access-Control-Allow-Origin * env=SAFE_RESOURCE # Redirect old battles to their corresponding replay From fb41336f9a1bf92e175de13962807356b6f6c7c9 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sat, 4 Nov 2023 16:18:46 +0000 Subject: [PATCH 534/770] Improve design - Updates New Replays for the design refresh - Updates STYLING.html for the design refresh Fixes #2177 --- js/client-battle.js | 2 +- js/client-teambuilder.js | 12 ++--- js/client-topbar.js | 2 +- js/client.js | 8 ++-- src/battle-log.ts | 1 + style/STYLING.html | 66 ++++++++++++++++++++++---- style/battle-log.css | 36 ++++++++++++-- style/battle.css | 3 +- style/client.css | 22 +-------- website/pages/contact-ja.md | 2 +- website/pages/contact.md | 2 +- website/replays/index.template.html | 13 ----- website/replays/src/replays-battle.tsx | 31 ++++++------ website/replays/src/replays.tsx | 4 +- website/style/global.css | 1 + 15 files changed, 130 insertions(+), 75 deletions(-) diff --git a/js/client-battle.js b/js/client-battle.js index a5c77e7223..5a03645c41 100644 --- a/js/client-battle.js +++ b/js/client-battle.js @@ -1512,7 +1512,7 @@ if (this.gameType === 'battle' && this.room.battle && !this.room.battle.rated) { buf += ' '; } - buf += '

    '; + buf += '

    '; this.$el.html(buf); }, replacePlayer: function (data) { diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 73bc87a674..871043bbe9 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -1202,12 +1202,12 @@ } for (i = 0; i < this.curSetList.length; i++) { if (this.curSetList.length < this.curTeam.capacity && this.deletedSet && i === this.deletedSetLoc) { - buf += '
  • '; + buf += '
  • '; } buf += this.renderSet(this.curSetList[i], i); } if (this.deletedSet && i === this.deletedSetLoc) { - buf += '
  • '; + buf += '
  • '; } if (i === 0) { buf += '
  • '; @@ -1243,7 +1243,7 @@ var buf = '
  • '; if (!set.species) { if (this.deletedSet) { - buf += '
    '; + buf += '
    '; } buf += '
    '; buf += '
    '; @@ -1594,9 +1594,9 @@ buf += '
    ' + this.clipboardInnerHTML() + '
    '; buf += '
    '; if (this.curTeam && this.curSetList.length < this.curTeam.capacity) { - buf += ''; + buf += ''; } - buf += ''; + buf += ''; buf += '
    '; buf += '
  • '; @@ -1766,7 +1766,7 @@ $setDiv.text('Sample sets: '); for (var set in sets) { - $setDiv.append(''); + $setDiv.append(''); } $setDiv.append(' (Smogon analysis)'); }, diff --git a/js/client-topbar.js b/js/client-topbar.js index 9d256098fc..635bfd5987 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -1070,7 +1070,7 @@ buf += '

    '; if (data.special === '@gmail') { buf += '
    [loading Google log-in button]
    '; - buf += '

    '; + buf += '

    '; } else { buf += '

    '; buf += '

    '; diff --git a/js/client.js b/js/client.js index d369b7f6ae..d32ae53e9d 100644 --- a/js/client.js +++ b/js/client.js @@ -2546,7 +2546,7 @@ function toId() { }, initialize: function (data) { if (!this.type) this.type = 'semimodal'; - this.$el.html('

    ' + (data.htmlMessage || BattleLog.parseMessage(data.message)) + '

    ' + (data.buttons || '') + '

    ').css('max-width', data.maxWidth || 480); + this.$el.html('

    ' + (data.htmlMessage || BattleLog.parseMessage(data.message)) + '

    ' + (data.buttons || '') + '

    ').css('max-width', data.maxWidth || 480); }, dispatchClickButton: function (e) { @@ -2924,7 +2924,7 @@ function toId() { buf += '

    The Wii U does not support secure connections.

    '; buf += '

    '; } else if (document.location.protocol === 'https:') { - buf += '

    '; + buf += '

    '; } else { buf += '

    '; } @@ -2978,7 +2978,7 @@ function toId() { var buf = ''; buf = '

    Your replay has been uploaded! It\'s available at:

    '; buf += '

    https://' + Config.routes.replays + '/' + data.id + '

    '; - buf += '

    '; + buf += '

    '; this.$el.html(buf).css('max-width', 620); }, clickClose: function () { @@ -3037,7 +3037,7 @@ function toId() { setTimeout(_.bind(this.rulesTimeout, this), 5000); } else { this.type = 'semimodal'; - buf += '

    '; + buf += '

    '; } this.$el.css('max-width', 760).html(buf); }, diff --git a/src/battle-log.ts b/src/battle-log.ts index dbc5e0f4b4..12ecd49140 100644 --- a/src/battle-log.ts +++ b/src/battle-log.ts @@ -83,6 +83,7 @@ export class BattleLog { } destroy() { this.elem.onscroll = null; + this.elem.innerHTML = ''; } addSeekEarlierButton() { if (this.skippedLines) return; diff --git a/style/STYLING.html b/style/STYLING.html index 348377bbd1..c3fcbaecf5 100644 --- a/style/STYLING.html +++ b/style/STYLING.html @@ -15,7 +15,7 @@ function customCssSuccess() { customCssLoaded = 'success'; updateCustomCss(); } - + \n'; buf += '
    \n'; buf += '\n'; buf += '
    \n'; From befbf585e64255aa1fc58c541aff19a46e284650 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sat, 4 Nov 2023 23:22:59 +0000 Subject: [PATCH 538/770] Fix more design refresh bugs - Teams in folders in the team dropdown were unstyled - `.button.disabled` wasn't taking precedence over `.button.notifying` --- js/client-mainmenu.js | 6 ++-- style/battle-log.css | 83 ++++++++++++++++++++++--------------------- style/battle.css | 2 +- 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index 825c87feb9..e1d9a44993 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -1443,7 +1443,7 @@ var count = 0; if (teamFormat) { bufs[curBuf] = '
  • ' + BattleLog.escapeFormat(teamFormat) + ' teams

  • '; - bufs[curBuf] += '
  • Group by folders
  • '; + bufs[curBuf] += '
  • '; for (var i = 0; i < teams.length; i++) { if ((!teams[i].format && !teamFormat) || teams[i].format === teamFormat) { var selected = (i === curTeam); @@ -1478,7 +1478,7 @@ if (count % bufBoundary === 0 && curBuf < 4) curBuf++; for (var j = 0; j < folderData.length; j++) { var selected = (folderData[j].id === curTeam); - bufs[curBuf] += '
  • '; + bufs[curBuf] += '
  • '; count++; if (count % bufBoundary === 0 && curBuf < 4) curBuf++; } @@ -1547,7 +1547,7 @@ } }, events: { - 'click [type="checkbox"]': 'foldersToggle', + 'click input[type=checkbox]': 'foldersToggle', }, moreTeams: function () { this.close(); diff --git a/style/battle-log.css b/style/battle-log.css index a3fbe550c3..ab4eed52a9 100644 --- a/style/battle-log.css +++ b/style/battle-log.css @@ -57,6 +57,10 @@ button, summary { cursor: pointer; touch-action: manipulation; } +button:disabled { + cursor: default; +} + .button { cursor: pointer; text-align: center; @@ -96,30 +100,6 @@ select.button { background: linear-gradient(to bottom, #bfbfbf, #f2f2f2); } -.button.disabled, -.button.disabled:hover, -.button.disabled:active, -.button:disabled, -.button:disabled:hover, -.button:disabled:active, -.button.cur, -.button.cur:hover { - cursor: default; - background: #EEEEEE; - border: 1px solid #CCCCCC; - color: #999999; - text-shadow: none; - box-shadow: 0 1px 2px rgba(0,0,0,.1); -} -.button.cur, -.button.cur:hover { - color: #444444; -} - -button:disabled { - cursor: default; -} - .button.notifying { border-color: #AA8866; background: #e3c3a3; @@ -152,6 +132,26 @@ button:disabled { color: #AA6600; } +.button.disabled, +.button.disabled:hover, +.button.disabled:active, +.button:disabled, +.button:disabled:hover, +.button:disabled:active, +.button.cur, +.button.cur:hover { + cursor: default; + background: #EEEEEE; + border: 1px solid #CCCCCC; + color: #999999; + text-shadow: none; + box-shadow: 0 1px 2px rgba(0,0,0,.1); +} +.button.cur, +.button.cur:hover { + color: #444444; +} + .button-first, .button-middle { border-top-right-radius: 0; border-bottom-right-radius: 0; @@ -188,23 +188,6 @@ button:disabled { border-color: #34373b; box-shadow: 0.5px 1px 2px rgba(255, 255, 255, 0.45); } -.dark .button.disabled, -.dark .button.disabled:hover, -.dark .button.disabled:active, -.dark .button:disabled, -.dark .button:disabled:hover, -.dark .button:disabled:active, -.dark .button.cur, -.dark .button.cur:hover { - background: #555555; - border-color: #34373b; - box-shadow: 0.5px 1px 2px rgba(255, 255, 255, 0.45); - color: #999999; -} -.dark .button.cur, -.dark .button.cur:hover { - color: #E9E9E9; -} .dark .button option, .dark .button optgroup { /* Chrome/Win does this thing where it takes
    G+lYb$mJMyKVJSb-@+ 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 Se6Rlj;0yjpSFKLPHvE6;*{-<& literal 0 HcmV?d00001 diff --git a/replay.pokemonshowdown.com/check-login.php b/replay.pokemonshowdown.com/check-login.php new file mode 100644 index 0000000000..28f50036c1 --- /dev/null +++ b/replay.pokemonshowdown.com/check-login.php @@ -0,0 +1,17 @@ + + * @license MIT + */ + +require '../lib/ntbb-session.lib.php'; + +echo ']' . ($curuser['loggedin'] ? $curuser['userid'] : '') . ','; + +echo $users->isSysop() ? '1' : ''; diff --git a/replay.pokemonshowdown.com/favicon.ico b/replay.pokemonshowdown.com/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..cf7439e089cb5fc368e569c457ed0ba32582a6fd GIT binary patch literal 42304 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%0DpR4H5-j=5 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 - Pokémon Showdown! - + + + @@ -122,11 +136,11 @@

    diff --git a/replays/replay-config.example.inc.php b/replay.pokemonshowdown.com/replay-config.example.inc.php similarity index 100% rename from replays/replay-config.example.inc.php rename to replay.pokemonshowdown.com/replay-config.example.inc.php diff --git a/replays/battle.php b/replay.pokemonshowdown.com/replay-manage.php similarity index 100% rename from replays/battle.php rename to replay.pokemonshowdown.com/replay-manage.php diff --git a/replays/battle.log.php b/replay.pokemonshowdown.com/replay.log.php similarity index 68% rename from replays/battle.log.php rename to replay.pokemonshowdown.com/replay.log.php index 5b5aeb6152..aa5f3dc1c8 100644 --- a/replays/battle.log.php +++ b/replay.pokemonshowdown.com/replay.log.php @@ -1,22 +1,22 @@ + * @license MIT + */ + error_reporting(E_ALL); ini_set('display_errors', TRUE); ini_set('display_startup_errors', TRUE); $manage = false; -// if (@$_REQUEST['name'] === 'smogtours-ou-509') { -// header('Content-type: text/plain'); -// readfile('js/smogtours-ou-509.log'); -// die(); -// } -// if (@$_REQUEST['name'] === 'ou-305002749') { -// header('Content-type: text/plain'); -// readfile('js/ou-305002749.log'); -// die(); -// } - require_once 'replays.lib.php'; $replay = null; @@ -31,8 +31,21 @@ // die($id . ' ' . $password); } +// $forcecache = isset($_REQUEST['forcecache8723']); +$forcecache = false; if ($id) { - $replay = $Replays->get($id); + if (file_exists('caches/' . $id . '.inc.php')) { + include 'caches/' . $id . '.inc.php'; + $replay['formatid'] = ''; + $cached = true; + } else { + require_once 'replays.lib.php'; + if (!$Replays->db && !$forcecache) { + header('HTTP/1.1 503 Service Unavailable'); + die(); + } + $replay = $Replays->get($id, $forcecache); + } } if (!$replay) { header('HTTP/1.1 404 Not Found'); diff --git a/replay.pokemonshowdown.com/replay.php b/replay.pokemonshowdown.com/replay.php new file mode 100644 index 0000000000..fb35465066 --- /dev/null +++ b/replay.pokemonshowdown.com/replay.php @@ -0,0 +1,64 @@ + + * @license MIT + */ + +error_reporting(E_ALL); +ini_set('display_errors', TRUE); +ini_set('display_startup_errors', TRUE); + +$manage = false; + +require_once 'replays.lib.php'; + +$replay = null; +$id = $_REQUEST['name'] ?? ''; +$password = ''; + +$fullid = $id; +if (substr($id, -2) === 'pw') { + $dashpos = strrpos($id, '-'); + $password = substr($id, $dashpos + 1, -2); + $id = substr($id, 0, $dashpos); + // die($id . ' ' . $password); +} + +// $forcecache = isset($_REQUEST['forcecache8723']); +$forcecache = false; +if ($id) { + if (file_exists('caches/' . $id . '.inc.php')) { + include 'caches/' . $id . '.inc.php'; + $replay['formatid'] = ''; + $cached = true; + } else { + require_once 'replays.lib.php'; + if (!$Replays->db && !$forcecache) { + header('HTTP/1.1 503 Service Unavailable'); + die(); + } + $replay = $Replays->exists($id, $forcecache); + } +} +if (!$replay) { + header('HTTP/1.1 404 Not Found'); + include '404.html'; + die(); +} +if ($replay['password'] ?? null) { + if ($password !== $replay['password']) { + header('HTTP/1.1 404 Not Found'); + include '404.html'; + die(); + } +} + +include 'index.html'; diff --git a/replays/replays.lib.php b/replay.pokemonshowdown.com/replays.lib.php similarity index 97% rename from replays/replays.lib.php rename to replay.pokemonshowdown.com/replays.lib.php index a7329159af..3c10873652 100644 --- a/replays/replays.lib.php +++ b/replay.pokemonshowdown.com/replays.lib.php @@ -65,6 +65,21 @@ function get($id, $force = false) { return $replay; } + function exists($id, $forcecache = false) { + if ($forcecache) return null; + + if (!$this->db) { + $this->init(); + } + + $res = $this->db->prepare("SELECT id, password FROM ps_replays WHERE id = ? LIMIT 1"); + $res->execute([$id]); + if (!$res) return null; + $replay = $res->fetch(); + if (!$replay) return null; + + return $replay; + } function edit(&$replay) { if ($replay['private'] === 3) { $replay['private'] = 3; diff --git a/replays/js/replay.js b/replay.pokemonshowdown.com/src/replay.js similarity index 99% rename from replays/js/replay.js rename to replay.pokemonshowdown.com/src/replay.js index 6c9da9a3bd..ac7c4ac123 100644 --- a/replays/js/replay.js +++ b/replay.pokemonshowdown.com/src/replay.js @@ -1,3 +1,5 @@ +// preserved for replay management + /* function updateProgress(done, a, b) { if (!battle.paused) return; diff --git a/website/replays/src/replays-battle.tsx b/replay.pokemonshowdown.com/src/replays-battle.tsx similarity index 98% rename from website/replays/src/replays-battle.tsx rename to replay.pokemonshowdown.com/src/replays-battle.tsx index fb1e3dcdb2..f7d1a42ed3 100644 --- a/website/replays/src/replays-battle.tsx +++ b/replay.pokemonshowdown.com/src/replays-battle.tsx @@ -3,9 +3,9 @@ import preact from 'preact'; import $ from 'jquery'; import {Net} from './utils'; import {PSRouter} from './replays'; -import {Battle} from '../../../src/battle'; -import {BattleLog} from '../../../src/battle-log'; -import {BattleSound} from '../../../src/battle-sound'; +import {Battle} from '../../src/battle'; +import {BattleLog} from '../../src/battle-log'; +import {BattleSound} from '../../src/battle-sound'; declare function toID(input: string): string; function showAd(id: string) { @@ -94,7 +94,7 @@ export class BattlePanel extends preact.Component<{id: string}> { this.battle = null; this.result = undefined; - Net(`https://replay.pokemonshowdown.com/${this.stripQuery(id)}.json`).get().then(result => { + Net(`/${this.stripQuery(id)}.json`).get().then(result => { const replay: NonNullable = JSON.parse(result); this.result = replay; const $base = $(this.base!); diff --git a/website/replays/src/replays.tsx b/replay.pokemonshowdown.com/src/replays.tsx similarity index 99% rename from website/replays/src/replays.tsx rename to replay.pokemonshowdown.com/src/replays.tsx index 0af6a9a073..3ee3b04412 100644 --- a/website/replays/src/replays.tsx +++ b/replay.pokemonshowdown.com/src/replays.tsx @@ -26,7 +26,7 @@ class SearchPanel extends preact.Component<{id: string}> { loggedInUserIsSysop = false; sort = 'date'; override componentDidMount() { - Net('check-login.php').get().then(result => { + Net('/check-login.php').get().then(result => { if (result.charAt(0) !== ']') return; const [userid, sysop] = result.slice(1).split(','); this.loggedInUser = userid; @@ -262,7 +262,7 @@ class FeaturedReplays extends preact.Component { kdarewolf vs. Onox
    Protean + prediction
    -
  • +
  • [gen6-anythinggoes]
    Anta2 vs. dscottnew
    Cheek Pouch
    diff --git a/website/replays/src/utils.ts b/replay.pokemonshowdown.com/src/utils.ts similarity index 100% rename from website/replays/src/utils.ts rename to replay.pokemonshowdown.com/src/utils.ts diff --git a/replays/theme/panels.lib.php b/replay.pokemonshowdown.com/theme/panels.lib.php similarity index 100% rename from replays/theme/panels.lib.php rename to replay.pokemonshowdown.com/theme/panels.lib.php diff --git a/replays/theme/wrapper.inc.template.php b/replay.pokemonshowdown.com/theme/wrapper.inc.template.php similarity index 100% rename from replays/theme/wrapper.inc.template.php rename to replay.pokemonshowdown.com/theme/wrapper.inc.template.php diff --git a/website/replays/check-login.php b/website/replays/check-login.php deleted file mode 100644 index 1a8693c8e9..0000000000 --- a/website/replays/check-login.php +++ /dev/null @@ -1,7 +0,0 @@ -isSysop() ? '1' : ''; diff --git a/website/style/global.css b/website/style/global.css index b9c8c6dcd3..9ecce7a9dd 100644 --- a/website/style/global.css +++ b/website/style/global.css @@ -79,7 +79,8 @@ header { background: linear-gradient(to bottom, #273661, #4c63a3); box-shadow: 0.5px 1px 2px rgba(255, 255, 255, 0.45), inset 0.5px 1px -1px rgba(255, 255, 255, 0.5); } -.nav a.cur, .nav a.cur:hover, .nav a.cur:active { +.nav a.cur, .nav a.cur:hover, .nav a.cur:active, +.dark .nav a.cur, .dark .nav a.cur:hover, .dark .nav a.cur:active { color: #CCCCCC; background: rgba(79, 109, 148, 0.7); box-shadow: 0.5px 1px 2px rgba(255, 255, 255, 0.45); From 51a285cd55d6527785d83ad3dfc8c494854ee754 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sun, 5 Nov 2023 23:24:40 +0000 Subject: [PATCH 540/770] Replays: Restore support for -restoreboost I was watching an old replay and noticed it no longer worked. Turn 7 of https://replay.pokemonshowdown.com/randombattle-247965078 Apparently when I did this rename, I didn't bother to make it backwards compatible with old replays? 9aba6a3ce6f02c83699aceb --- src/battle-text-parser.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/battle-text-parser.ts b/src/battle-text-parser.ts index 11da55e34a..6ef36c0927 100644 --- a/src/battle-text-parser.ts +++ b/src/battle-text-parser.ts @@ -101,6 +101,11 @@ class BattleTextParser { return {group, name, away, status}; } + /** + * Old replays may use syntax we no longer use, so this function upgrades + * them to modern versions. Used to keep battle.ts itself cleaner. Not + * guaranteed to mutate or not mutate its inputs. + */ static upgradeArgs({args, kwArgs}: {args: Args, kwArgs: KWArgs}): {args: Args, kwArgs: KWArgs} { switch (args[0]) { case '-activate': { @@ -189,6 +194,11 @@ class BattleTextParser { break; } + case '-restoreboost': { + args[0] = '-clearnegativeboost'; + break; + } + case '-nothing': // OLD: |-nothing // NEW: |-activate||move:Splash From fb049bef90beee2946e04f81cb3b9d6e760a7f23 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Sun, 5 Nov 2023 18:36:55 -0600 Subject: [PATCH 541/770] Storage: Ensure teams of nonstandard length don't duplicate on load --- js/storage.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/storage.js b/js/storage.js index 7c8457b218..b77f04bff0 100644 --- a/js/storage.js +++ b/js/storage.js @@ -597,6 +597,7 @@ Storage.compareTeams = function (serverTeam, localTeam) { for (var j = 0; j < otherMons.length; j++) { if (toID(otherMons[j].species) === toID(mons[i])) { matches++; + break; } } } From 3a8a7934784a659826486caae6deeb99ea4d2c7a Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Tue, 7 Nov 2023 20:56:33 +0000 Subject: [PATCH 542/770] Support old replay search API I completely missed that this was being used... --- replay.pokemonshowdown.com/.htaccess | 1 + replay.pokemonshowdown.com/replay.log.php | 2 +- .../search.json.php | 2 +- {old-replays => replay.pokemonshowdown.com}/search.notjson.php | 0 4 files changed, 3 insertions(+), 2 deletions(-) rename old-replays/search.yesjson.php => replay.pokemonshowdown.com/search.json.php (96%) rename {old-replays => replay.pokemonshowdown.com}/search.notjson.php (100%) diff --git a/replay.pokemonshowdown.com/.htaccess b/replay.pokemonshowdown.com/.htaccess index 92b3bd965b..da2677be0f 100644 --- a/replay.pokemonshowdown.com/.htaccess +++ b/replay.pokemonshowdown.com/.htaccess @@ -1,6 +1,7 @@ RewriteEngine on RewriteRule ^api(/.*)?$ http://localhost:9000/api$1 [P,L] +RewriteRule ^search\.json$ search.json.php [L,QSA] RewriteRule ^([A-Za-z0-9-]+)$ replay.php?name=$1 [L,QSA] RewriteRule ^([A-Za-z0-9-]+)/manage$ replay-manage.php?name=$1&manage [L,QSA] RewriteRule ^([A-Za-z0-9-]+)\.log$ replay.log.php?name=$1 [L,QSA] diff --git a/replay.pokemonshowdown.com/replay.log.php b/replay.pokemonshowdown.com/replay.log.php index aa5f3dc1c8..1d5e9d0642 100644 --- a/replay.pokemonshowdown.com/replay.log.php +++ b/replay.pokemonshowdown.com/replay.log.php @@ -60,7 +60,7 @@ $replay['log'] = str_replace("\r","",$replay['log']); -if ($replay['inputlog']) { +if (@$replay['inputlog']) { if (substr($replay['formatid'], -12) === 'randombattle' || substr($replay['formatid'], -19) === 'randomdoublesbattle' || $replay['formatid'] === 'gen7challengecup' || $replay['formatid'] === 'gen7challengecup1v1' || $replay['formatid'] === 'gen7battlefactory' || $replay['formatid'] === 'gen7bssfactory' || $replay['formatid'] === 'gen7hackmonscup' || $manage) { // ok } else { diff --git a/old-replays/search.yesjson.php b/replay.pokemonshowdown.com/search.json.php similarity index 96% rename from old-replays/search.yesjson.php rename to replay.pokemonshowdown.com/search.json.php index c714bea56e..ea91581205 100644 --- a/old-replays/search.yesjson.php +++ b/replay.pokemonshowdown.com/search.json.php @@ -10,7 +10,7 @@ header('Content-Type: application/json'); header('Access-Control-Allow-Origin: *'); -require_once '../../replays/replays.lib.php'; +require_once 'replays.lib.php'; $username = $Replays->toID($username); $isPrivateAllowed = false; diff --git a/old-replays/search.notjson.php b/replay.pokemonshowdown.com/search.notjson.php similarity index 100% rename from old-replays/search.notjson.php rename to replay.pokemonshowdown.com/search.notjson.php From a083b1dd42c78ac4c4dd38c0b44ccbd4afee83c6 Mon Sep 17 00:00:00 2001 From: LumarisX <65790297+LumarisX@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:20:27 -0800 Subject: [PATCH 543/770] Give all data/ files Access-Control-Allow-Origin header (#2183) --- .htaccess | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.htaccess b/.htaccess index bea8fe2d1d..bdc8998471 100644 --- a/.htaccess +++ b/.htaccess @@ -91,7 +91,7 @@ RewriteCond %{HTTP_HOST} ^www\.play\.pokemonshowdown\.com$ [NC] RewriteRule ^(.*) https://play.pokemonshowdown.com/$1 [R=301,L] RewriteRule ^style/fonts?/.*?\.(eot|svg|ttf|woff|woff2)$ - [E=SAFE_RESOURCE:1] -RewriteRule ^data/(moves|abilities|learnsets).json$ - [E=SAFE_RESOURCE:1] +RewriteRule ^data\/.*\.js(?:on)?$ - [E=SAFE_RESOURCE:1] Header set Access-Control-Allow-Origin * env=SAFE_RESOURCE # Redirect old battles to their corresponding replay From 57e8302147b218bf526f5e563ffde892a101b228 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 8 Nov 2023 06:20:39 +0000 Subject: [PATCH 544/770] Replays: Support "music off, effects on" sound mode --- replay.pokemonshowdown.com/src/replays-battle.tsx | 8 ++++++-- src/battle-animations.ts | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/replay.pokemonshowdown.com/src/replays-battle.tsx b/replay.pokemonshowdown.com/src/replays-battle.tsx index f7d1a42ed3..ea9f9826d9 100644 --- a/replay.pokemonshowdown.com/src/replays-battle.tsx +++ b/replay.pokemonshowdown.com/src/replays-battle.tsx @@ -308,6 +308,9 @@ export class BattlePanel extends preact.Component<{id: string}> { changeSound = (e: Event) => { const muted = (e.target as HTMLSelectElement).value; this.battle?.setMute(muted === 'off'); + // Wolfram Alpha says that default volume is 100 e^(-(2 log^2(2))/log(10)) which is around 65.881 + BattleSound.setBgmVolume(muted === 'musicoff' ? 0 : 65.881258001265573); + this.forceUpdate(); }; openTurn = (e: Event) => { this.turnView = `${this.battle?.turn}` || true; @@ -419,14 +422,15 @@ export class BattlePanel extends preact.Component<{id: string}> { {} {}

    {} + {}

    '; From 8750d6b985194f98700ecb309b9c927ec29bfdb6 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Fri, 10 Nov 2023 09:12:04 -0600 Subject: [PATCH 551/770] Add home button for friends list Z said this was fine. --- js/client-mainmenu.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index 148b2a81ec..3267a20e28 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -57,7 +57,8 @@ buf += ''; buf += ''; + buf += '

    '; + buf += '

    '; this.$('.mainmenu').html(buf); From 626ececf1731ca98f31a8ccbed0bd3d59f45aff1 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:13:47 -0600 Subject: [PATCH 552/770] Storage: Add colors to all 6 mainmenu buttons Previously, it was only doing 5, which was hardcoded. I made this a top-level variable for future changes because this one took a while (finding all the references took a bit, numbers are not easily searched in this file.) --- js/storage.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/js/storage.js b/js/storage.js index 5b2f0cf2b9..3eeaa4e332 100644 --- a/js/storage.js +++ b/js/storage.js @@ -30,6 +30,9 @@ Storage.safeJSON = function (callback) { Storage.bg = { id: '', changeCount: 0, + // futureproofing in case we ever add more? + // because doing this once was annoying + MENU_BUTTONS: 6, set: function (bgUrl, bgid, noSave) { if (!this.load(bgUrl, bgid)) { this.extractMenuColors(bgUrl, bgid, noSave); @@ -121,7 +124,8 @@ Storage.bg = { var g = parseInt(bgUrl.slice(3, 5), 16) / 255; var b = parseInt(bgUrl.slice(5, 7), 16) / 255; var hs = this.getHueSat(r, g, b); - hues = [hs, hs, hs, hs, hs, hs]; + hues = []; + for (var i = 0; i < Storage.bg.MENU_BUTTONS; i++) hues.push(hs); } if (hues) { this.loadHues(hues); @@ -131,7 +135,7 @@ Storage.bg = { loadHues: function (hues) { $('#mainmenubuttoncolors').remove(); var cssBuf = ''; - for (var i = 0; i < 5; i++) { + for (var i = 0; i < Storage.bg.MENU_BUTTONS; i++) { var n = i + 1; var hs = hues[i]; cssBuf += 'body .button.mainmenu' + n + ' { background: linear-gradient(to bottom, hsl(' + hs + ',72%), hsl(' + hs + ',52%)); border-color: hsl(' + hs + ',40%); }\n'; @@ -149,13 +153,15 @@ Storage.bg = { // or localStorage throws try { var colorThief = new ColorThief(); - var colors = colorThief.getPalette(img, 5); + var colors = colorThief.getPalette(img, Storage.bg.MENU_BUTTONS); + window.colors = colors; var hues = []; if (!colors) { - hues = ['0, 0%', '0, 0%', '0, 0%', '0, 0%', '0, 0%']; + hues = []; + for (var i = 0; i < Storage.bg.MENU_BUTTONS; i++) hues.push('0, 0%'); } else { - for (var i = 0; i < 5; i++) { + for (var i = 0; i < Storage.bg.MENU_BUTTONS; i++) { var color = colors[i]; var hs = Storage.bg.getHueSat(color[0] / 255, color[1] / 255, color[2] / 255); hues.unshift(hs); From e0e2ea0964ee059419e306866f01800b158f1ce6 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:52:40 -0700 Subject: [PATCH 553/770] Add some new move animations (#2185) * strt new nims * Add moon image to other moon-y moves * oopz * build fix --- fx/moon.png | Bin 0 -> 4824 bytes src/battle-animations-moves.ts | 433 +++++++++++++++++++++++++-------- src/battle-animations.ts | 10 +- 3 files changed, 338 insertions(+), 105 deletions(-) create mode 100644 fx/moon.png diff --git a/fx/moon.png b/fx/moon.png new file mode 100644 index 0000000000000000000000000000000000000000..4f859a20a41babbc4cf512a60de19af7738e0961 GIT binary patch literal 4824 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'); this.$fx.append($effect); + if (additionalCss) $effect.css(additionalCss); $effect = this.$fx.children().last(); if (start.time) { @@ -2983,6 +2987,10 @@ const BattleEffects: {[k: string]: SpriteData} = { url: 'flareball.png', w: 100, h: 100, }, + moon: { + url: 'moon.png', // by Kalalokki + w: 100, h: 100, + }, pokeball: { url: 'pokeball.png', w: 24, h: 24, From dbd4a9ec66c51cdba67acd494d9348f8a147722e Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Tue, 14 Nov 2023 02:20:43 -0700 Subject: [PATCH 554/770] Add Ivy Cudgel and Matcha Gotcha animations --- src/battle-animations-moves.ts | 508 +++++++++++++++++++++++++++++++++ 1 file changed, 508 insertions(+) diff --git a/src/battle-animations-moves.ts b/src/battle-animations-moves.ts index 34610dff60..1805c9b67d 100644 --- a/src/battle-animations-moves.ts +++ b/src/battle-animations-moves.ts @@ -5075,6 +5075,362 @@ export const BattleMoveAnims: AnimTable = { BattleOtherAnims.contactattack.anim(scene, [attacker, defender]); }, }, + ivycudgel: { + anim(scene, [attacker, defender]) { + scene.showEffect('energyball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 420, + }, { + x: defender.leftof(-20), + y: defender.y, + z: defender.behind(20), + scale: 3, + opacity: 0, + time: 700, + }, 'linear'); + scene.showEffect('energyball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 520, + }, { + x: defender.leftof(-20), + y: defender.y, + z: defender.behind(20), + scale: 3, + opacity: 0, + time: 800, + }, 'linear'); + scene.showEffect('leaf1', { + x: defender.x, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 500, + }, { + x: defender.x, + y: defender.y + 10, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 700, + }, 'decel', 'fade'); + scene.showEffect('leaf2', { + x: defender.x - 40, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 600, + }, { + x: defender.x - 30, + y: defender.y, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 800, + }, 'decel', 'fade'); + scene.showEffect('leaf2', { + x: defender.x + 40, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 700, + }, { + x: defender.x + 40, + y: defender.y, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 900, + }, 'decel', 'fade'); + defender.delay(420); + defender.anim({ + y: defender.y - 30, + z: defender.behind(20), + yscale: 0.5, + time: 0, + }, 'swing'); + defender.anim({ + time: 480, + }, 'swing'); + }, + }, + ivycudgelwater: { + anim(scene, [attacker, defender]) { + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 420, + }, { + x: defender.leftof(-20), + y: defender.y, + z: defender.behind(20), + scale: 3, + opacity: 0, + time: 700, + }, 'linear'); + scene.showEffect('waterwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 520, + }, { + x: defender.leftof(-20), + y: defender.y, + z: defender.behind(20), + scale: 3, + opacity: 0, + time: 800, + }, 'linear'); + scene.showEffect('iceball', { + x: defender.x, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 500, + }, { + x: defender.x, + y: defender.y + 10, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 700, + }, 'decel', 'fade'); + scene.showEffect('iceball', { + x: defender.x - 40, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 600, + }, { + x: defender.x - 30, + y: defender.y, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 800, + }, 'decel', 'fade'); + scene.showEffect('iceball', { + x: defender.x + 40, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 700, + }, { + x: defender.x + 40, + y: defender.y, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 900, + }, 'decel', 'fade'); + defender.delay(420); + defender.anim({ + y: defender.y - 30, + z: defender.behind(20), + yscale: 0.5, + time: 0, + }, 'swing'); + defender.anim({ + time: 480, + }, 'swing'); + }, + }, + ivycudgelfire: { + anim(scene, [attacker, defender]) { + scene.showEffect('flareball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 420, + }, { + x: defender.leftof(-20), + y: defender.y, + z: defender.behind(20), + scale: 3, + opacity: 0, + time: 700, + }, 'linear'); + scene.showEffect('flareball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 520, + }, { + x: defender.leftof(-20), + y: defender.y, + z: defender.behind(20), + scale: 3, + opacity: 0, + time: 800, + }, 'linear'); + scene.showEffect('fireball', { + x: defender.x, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 500, + }, { + x: defender.x, + y: defender.y + 10, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 700, + }, 'decel', 'fade'); + scene.showEffect('fireball', { + x: defender.x - 40, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 600, + }, { + x: defender.x - 30, + y: defender.y, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 800, + }, 'decel', 'fade'); + scene.showEffect('fireball', { + x: defender.x + 40, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 700, + }, { + x: defender.x + 40, + y: defender.y, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 900, + }, 'decel', 'fade'); + defender.delay(420); + defender.anim({ + y: defender.y - 30, + z: defender.behind(20), + yscale: 0.5, + time: 0, + }, 'swing'); + defender.anim({ + time: 480, + }, 'swing'); + }, + }, + ivycudgelrock: { + anim(scene, [attacker, defender]) { + scene.showEffect('mudwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 420, + }, { + x: defender.leftof(-20), + y: defender.y, + z: defender.behind(20), + scale: 3, + opacity: 0, + time: 700, + }, 'linear'); + scene.showEffect('mudwisp', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 520, + }, { + x: defender.leftof(-20), + y: defender.y, + z: defender.behind(20), + scale: 3, + opacity: 0, + time: 800, + }, 'linear'); + scene.showEffect('rock1', { + x: defender.x, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 500, + }, { + x: defender.x, + y: defender.y + 10, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 700, + }, 'decel', 'fade'); + scene.showEffect('rock2', { + x: defender.x - 40, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 600, + }, { + x: defender.x - 30, + y: defender.y, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 800, + }, 'decel', 'fade'); + scene.showEffect('rock3', { + x: defender.x + 40, + y: defender.y - 40, + z: defender.z, + scale: 1, + opacity: 1, + time: 700, + }, { + x: defender.x + 40, + y: defender.y, + z: defender.z, + scale: 1.25, + opacity: 0.4, + time: 900, + }, 'decel', 'fade'); + defender.delay(420); + defender.anim({ + y: defender.y - 30, + z: defender.behind(20), + yscale: 0.5, + time: 0, + }, 'swing'); + defender.anim({ + time: 480, + }, 'swing'); + }, + }, crushclaw: { anim: BattleOtherAnims.clawattack.anim, }, @@ -10650,6 +11006,158 @@ export const BattleMoveAnims: AnimTable = { }, 'swing'); }, }, + matchagotcha: { + anim(scene, [attacker, ...defenders]) { + for (let i = 0; i < 10; i++) { + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 0, + }, { + x: attacker.x + (100 / i), + y: attacker.y + (i * 10), + scale: 1, + opacity: 0, + time: 300, + }, 'ballistic'); + } + + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 0, + }, { + x: attacker.x - 25, + y: attacker.y - 25, + scale: 2, + opacity: 0, + time: 300, + }, 'ballistic'); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 150, + }, { + x: attacker.x + 30, + y: attacker.y - 20, + scale: 2, + opacity: 0, + time: 450, + }, 'ballistic'); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 250, + }, { + x: attacker.x + 5, + y: attacker.y - 40, + scale: 2, + opacity: 0, + time: 550, + }, 'ballistic'); + scene.showEffect('energyball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 1, + time: 300, + }, { + x: attacker.x - 20, + y: attacker.y - 20, + scale: 2, + opacity: 0, + time: 600, + }, 'ballistic'); + + for (const defender of defenders) { + scene.showEffect('energyball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 600, + }, { + scale: 5, + opacity: 0, + time: 900, + }, 'linear'); + scene.showEffect('energyball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0, + opacity: 1, + time: 700, + }, { + scale: 8, + opacity: 0, + time: 1000, + }, 'linear'); + scene.showEffect('wisp', { + x: defender.x + 30, + y: defender.y, + z: defender.z, + scale: 1, + opacity: 1, + time: 1010, + }, { + y: defender.y + 60, + opacity: 0.2, + time: 1410, + }, 'linear', 'fade'); + scene.showEffect('wisp', { + x: defender.x - 30, + y: defender.y, + z: defender.z, + scale: 1, + opacity: 1, + time: 1110, + }, { + y: defender.y + 60, + opacity: 0.2, + time: 1510, + }, 'linear', 'fade'); + scene.showEffect('wisp', { + x: defender.x + 15, + y: defender.y, + z: defender.z, + scale: 1, + opacity: 1, + time: 1210, + }, { + y: defender.y + 60, + opacity: 0.2, + time: 1610, + }, 'linear', 'fade'); + scene.showEffect('wisp', { + x: defender.x - 15, + y: defender.y, + z: defender.z, + scale: 1, + opacity: 1, + time: 1310, + }, { + y: defender.y + 60, + opacity: 0.2, + time: 1710, + }, 'linear', 'fade'); + } + }, + }, flamecharge: { anim(scene, [attacker, defender]) { scene.showEffect('fireball', { From 21de8d92c6620fac6ec60b13546229b9d59e3736 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Tue, 14 Nov 2023 07:12:56 +0000 Subject: [PATCH 555/770] Remove old action.php and replays Our new API replacement for action.php is in https://github.com/smogon/pokemon-showdown-loginserver I haven't completely deleted the old-replays folder because there are some things we haven't replaced that I don't know what to do with... I guess that'll come in a future commit. --- action.php | 39 - lib/dispatcher.lib.php | 555 - old-replays/.htaccess | 40 - old-replays/404.php | 46 - old-replays/503.php | 43 - old-replays/apple-touch-icon.png | Bin 45373 -> 0 bytes old-replays/build | 48 - old-replays/favicon.ico | Bin 318 -> 0 bytes old-replays/index.php | 246 - old-replays/js/ou-305002749.log | 14927 -------------------------- old-replays/js/smogtours-ou-509.log | 5064 --------- old-replays/search.json.php | 51 - old-replays/search.php | 277 - 13 files changed, 21336 deletions(-) delete mode 100644 action.php delete mode 100644 lib/dispatcher.lib.php delete mode 100644 old-replays/.htaccess delete mode 100644 old-replays/404.php delete mode 100644 old-replays/503.php delete mode 100644 old-replays/apple-touch-icon.png delete mode 100755 old-replays/build delete mode 100644 old-replays/favicon.ico delete mode 100644 old-replays/index.php delete mode 100644 old-replays/js/ou-305002749.log delete mode 100644 old-replays/js/smogtours-ou-509.log delete mode 100644 old-replays/search.json.php delete mode 100644 old-replays/search.php diff --git a/action.php b/action.php deleted file mode 100644 index fc8b68ea1d..0000000000 --- a/action.php +++ /dev/null @@ -1,39 +0,0 @@ - - -*/ - -error_reporting(E_ALL); - -include_once __DIR__ . '/config/config.inc.php'; - -if (@$_GET['act'] === 'dlteam') { - header("Content-Type: text/plain; charset=utf-8"); - if (substr(@$_SERVER['HTTP_REFERER'], 0, 32) !== 'https://' . $psconfig['routes']['client']) { - // since this is only to support Chrome on HTTPS, we can get away with a very specific referer check - die("access denied"); - } - echo base64_decode(@$_GET['team']); - die(); -} - -if (preg_match('/^http\\:\\/\\/[a-z0-9]+\\.psim\\.us\\//', $_SERVER['HTTP_REFERER'] ?? '')) { - header("Access-Control-Allow-Origin: *"); -} else if ($_POST['sid'] ?? null) { - header("Access-Control-Allow-Origin: *"); -} -// header("X-Debug: " . @$_SERVER['HTTP_REFERER']); - -require_once __DIR__ . '/lib/ntbb-session.lib.php'; -include_once __DIR__ . '/config/servers.inc.php'; -include_once __DIR__ . '/lib/dispatcher.lib.php'; - -$dispatcher = new ActionDispatcher(array( - new DefaultActionHandler(), - new LadderActionHandler() -)); -$dispatcher->executeActions(); diff --git a/lib/dispatcher.lib.php b/lib/dispatcher.lib.php deleted file mode 100644 index 809a79b96a..0000000000 --- a/lib/dispatcher.lib.php +++ /dev/null @@ -1,555 +0,0 @@ - - * - * This could let them steal the secrets. In modern times, browsers - * are protected against this kind of attack, but our `]` adds some - * safety for older browsers. - * - * Adding `]` to the beginning makes sure that the output is a syntax - * error in JS, so treating it as a JS file will simply crash and fail. - */ - private $outPrefix = ']'; - private $outArray = array(); - - public function __construct($handlers) { - $this->handlers = $handlers; - if (empty($_REQUEST)) { - $this->reqs = null; - if (substr($_SERVER["CONTENT_TYPE"] ?? '', 0, 16) === 'application/json') { - // screw you too Axios - // also come on PHP, you could just support JSON natively instead of putting me through this - $input = trim(file_get_contents('php://input')); - if ($input[0] === '[') { - $this->reqs = json_decode($input, true); - } else if ($input[0] === '{') { - $this->reqs = [json_decode($input, true)]; - } - } - - if (empty($this->reqs)) die("no request data found - you need to send some sort of data"); - $_POST['is_post_request'] = true; - } else { - $this->reqs = [$_REQUEST]; - } - if (@$_REQUEST['json']) { - $this->reqs = json_decode($_REQUEST['json'], true); - $this->multiReqs = true; - } - } - - public function setPrefix($prefix) { - $this->outPrefix = $prefix; - } - - public function getServerHostName($serverid) { - global $PokemonServers; - $server = @$PokemonServers[$serverid]; - return $server ? $server['server'] : $serverid; - } - - public function verifyCrossDomainRequest() { - global $psconfig; - // No cross-domain multi-requests for security reasons. - // No need to do anything if this isn't a cross-domain request. - if ($this->multiReqs || !isset($_SERVER['HTTP_ORIGIN'])) { - return ''; - } - - $origin = $_SERVER['HTTP_ORIGIN']; - $prefix = null; - foreach ($psconfig['cors'] as $i => &$j) { - if (!preg_match($i, $origin)) continue; - $prefix = $j; - break; - } - if ($prefix === null) { - // Bogus request. - return ''; - } - - // Valid CORS request. - header('Access-Control-Allow-Origin: ' . $origin); - header('Access-Control-Allow-Credentials: true'); - return $prefix; - } - - public function getIp() { - global $users; - return $users->getIp(); - } - - public function findServer() { - global $PokemonServers; - - $serverid = @$this->reqData['serverid']; - $server = null; - $ip = $this->getIp(); - if (!isset($PokemonServers[$serverid])) { - // Try to find the server by source IP, rather than by serverid. - if ($serverid === 'testtimeout') { - foreach ($PokemonServers as &$i) { - gethostbyname($i['server']); - } - } - return null; - } else { - $server = & $PokemonServers[$serverid]; - if (empty($server['skipipcheck']) && empty($server['token']) && $serverid !== 'showdown') { - if (!isset($server['ipcache'])) { - $server['ipcache'] = gethostbyname($server['server']); - } - if ($ip !== $server['ipcache']) return null; - } - } - if (!empty($server['token'])) { - if ($server['token'] !== md5($this->reqData['servertoken'] ?? '')) return null; - } - return $server; - } - - public function executeActions() { - $outArray = null; - if ($this->multiReqs) $outArray = array(); - - foreach ($this->reqs as $this->reqData) { - $this->reqData = array_merge($_REQUEST, $this->reqData); - if (!isset($this->reqData['act'])) die("action not found - make sure your request data includes act=something"); - $action = $this->reqData['act']; - if (!ctype_alnum($action)) die("invalid action: " . var_export($action, true)); - $out = array(); - - foreach ($this->handlers as &$i) { - if (is_callable(array($i, $action))) { - $i->$action($this, $this->reqData, $out); - } - } - - if ($this->multiReqs) $outArray[] = $out; - } - // json output - if ($this->outPrefix !== '') { - // Technically this is not JSON because of the initial prefix. - header('Content-Type: text/plain; charset=utf-8'); - } else { - header('Content-Type: application/json'); - } - if ($this->multiReqs) { - die($this->outPrefix . json_encode($outArray)); - } else { - die($this->outPrefix . json_encode($out)); - } - } -} - -class DefaultActionHandler { - public function login($dispatcher, &$reqData, &$out) { - global $users, $curuser; - $challengeprefix = $dispatcher->verifyCrossDomainRequest(); - - if (!$_POST) die('for security reasons, logins must happen with POST data'); - if (empty($reqData['name']) || empty($reqData['pass'])) die('incorrect login data, you need "name" and "pass" fields'); - try { - $users->login($reqData['name'], $reqData['pass']); - } catch (Exception $e) { - $out['error'] = $e->getMessage() . "\n" . $e->getFile() . '(' . $e->getLine() . ')' . "\n" . $e->getTraceAsString(); - } - unset($curuser['userdata']); - $out['curuser'] = $curuser; - $out['actionsuccess'] = ($curuser ? $curuser['loggedin'] : false); - $serverhostname = '' . $dispatcher->getServerHostName(@$reqData['serverid']); - $challengekeyid = !isset($reqData['challengekeyid']) ? -1 : intval($reqData['challengekeyid']); - $challenge = !isset($reqData['challenge']) ? '' : $reqData['challenge']; - if (!$challenge) { - $challenge = !isset($reqData['challstr']) ? '' : $reqData['challstr']; - } - $out['assertion'] = $users->getAssertion($curuser['userid'], $serverhostname, null, - $challengekeyid, $challenge, $challengeprefix); - } - - public function register($dispatcher, &$reqData, &$out) { - global $users, $curuser; - $challengeprefix = $dispatcher->verifyCrossDomainRequest(); - - $serverhostname = '' . $dispatcher->getServerHostName(@$reqData['serverid']); - $user = [ - 'username' => @$_POST['username'], - ]; - $userid = $users->userid($user['username']); - if ((mb_strlen($userid) < 1) || ctype_digit($userid)) { - $out['actionerror'] = 'Your username must contain at least one letter.'; - } else if (substr($userid, 0, 5) === 'guest') { - $out['actionerror'] = 'Your username cannot start with \'guest\'.'; - } else if (mb_strlen($user['username']) > 18) { - $out['actionerror'] = 'Your username must be less than 19 characters long.'; - } else if (mb_strlen(@$_POST['password']) < 5) { - $out['actionerror'] = 'Your password must be at least 5 characters long.'; - } else if (@$_POST['password'] !== @$_POST['cpassword']) { - $out['actionerror'] = 'Your passwords do not match.'; - } else if (trim(strtolower(@$_POST['captcha'])) !== 'pikachu') { - $out['actionerror'] = 'Please answer the anti-spam question given.'; - } else if (($registrationcount = $users->getRecentRegistrationCount()) === false) { - $out['actionerror'] = 'A database error occurred. Please try again.'; - } else if ($registrationcount >= 2) { - $out['actionerror'] = 'You can\'t register more than two usernames every two hours. Try again later.'; - } else if ($user = $users->addUser($user, $_POST['password'])) { - $challengekeyid = !isset($reqData['challengekeyid']) ? -1 : intval($reqData['challengekeyid']); - $challenge = !isset($reqData['challenge']) ? '' : $reqData['challenge']; - if (!$challenge) { - $challenge = !isset($reqData['challstr']) ? '' : $reqData['challstr']; - } - $out['curuser'] = $user; - $out['assertion'] = $users->getAssertion($user['userid'], - $serverhostname, $user, $challengekeyid, $challenge, $challengeprefix); - $out['actionsuccess'] = true; - } else { - $out['actionerror'] = 'Your username is already taken.'; - } - } - - public function changepassword($dispatcher, &$reqData, &$out) { - global $users, $curuser; - - if (!$_POST || - !isset($reqData['oldpassword']) || - !isset($reqData['password']) || - !isset($reqData['cpassword'])) { - $out['actionerror'] = 'Invalid request.'; - } else if (!$curuser['loggedin']) { - $out['actionerror'] = 'Your session has expired. Please log in again.'; - } else if ($reqData['password'] !== $reqData['cpassword']) { - $out['actionerror'] = 'Your new passwords do not match.'; - } else if (!$users->passwordVerify($curuser['userid'], $reqData['oldpassword'])) { - $out['actionerror'] = 'Your old password was incorrect.'; - } else if (mb_strlen($reqData['password']) < 5) { - $out['actionerror'] = 'Your new password must be at least 5 characters long.'; - } else if (!$users->modifyUser($curuser['userid'], array( - 'password' => $reqData['password']))) { - $out['actionerror'] = 'A database error occurred. Please try again.'; - } else { - $out['actionsuccess'] = true; - } - } - - public function changeusername($dispatcher, &$reqData, &$out) { - global $users, $curuser; - - if (!$_POST || - !isset($reqData['username'])) { - $out['actionerror'] = 'Invalid request.'; - } else if (!$curuser['loggedin']) { - $out['actionerror'] = 'Your session has expired. Please log in again.'; - } else if (!$users->modifyUser($curuser['userid'], array( - 'username' => $reqData['username']))) { - $out['actionerror'] = 'A database error occurred. Please try again.'; - } else { - $out['actionsuccess'] = true; - } - } - - public function logout($dispatcher, &$reqData, &$out) { - global $users, $curuser, $psconfig; - - if (!$_POST || - !isset($reqData['userid']) || - // some CSRF protection (client must know current userid) - ($reqData['userid'] !== $curuser['userid'])) { - die; - } - $users->logout(); // this kills the `sid` cookie - setcookie('showdown_username', '', time()-60*60*24*2, '/', $psconfig['routes']['client']); - $out['actionsuccess'] = true; - } - - public function getassertion($dispatcher, &$reqData, &$out) { - global $users, $curuser; - $challengeprefix = $dispatcher->verifyCrossDomainRequest(); - - $serverhostname = '' . $dispatcher->getServerHostName(@$reqData['serverid']); - $challengekeyid = !isset($reqData['challengekeyid']) ? -1 : intval($reqData['challengekeyid']); - $challenge = !isset($reqData['challenge']) ? '' : $reqData['challenge']; - if (!$challenge) { - $challenge = !isset($reqData['challstr']) ? '' : $reqData['challstr']; - } - header('Content-Type: text/plain; charset=utf-8'); - if (empty($reqData['userid'])) { - $userid = $curuser['userid']; - if ($userid === 'guest') { - // Special error message for this case. - die(';'); - } - } else { - $userid = $users->userid($reqData['userid']); - } - $serverhostname = htmlspecialchars($serverhostname); // Protect against theoretical IE6 XSS - die($users->getAssertion($userid, $serverhostname, null, $challengekeyid, $challenge, $challengeprefix)); - } - - public function upkeep($dispatcher, &$reqData, &$out) { - global $users, $curuser; - $challengeprefix = $dispatcher->verifyCrossDomainRequest(); - - $out['loggedin'] = $curuser['loggedin']; - $userid = ''; - if ($curuser['loggedin']) { - $out['username'] = $curuser['username']; - $userid = $curuser['userid']; - } else if (isset($_COOKIE['showdown_username'])) { - $out['username'] = $_COOKIE['showdown_username']; - $userid = $users->userid($out['username']); - } - if ($userid !== '') { - $serverhostname = '' . $dispatcher->getServerHostName(@$reqData['serverid']); - $challengekeyid = !isset($reqData['challengekeyid']) ? -1 : intval($reqData['challengekeyid']); - $challenge = !isset($reqData['challenge']) ? '' : $reqData['challenge']; - if (!$challenge) { - $challenge = !isset($reqData['challstr']) ? '' : $reqData['challstr']; - } - $out['assertion'] = $users->getAssertion($userid, $serverhostname, null, $challengekeyid, $challenge, $challengeprefix); - } - } - - public function updateuserstats($dispatcher, &$reqData, &$out) { - global $psdb; - - $server = $dispatcher->findServer(); - if (!$server) { - $out = 0; - return; - } - - $date = @$reqData['date']; - $usercount = @$reqData['users']; - if (!is_numeric($date) || !is_numeric($usercount)) { - $out = 0; - return; - } - - $out = !!$psdb->query( - "INSERT INTO `ntbb_userstats` (`serverid`, `date`, `usercount`) " . - "VALUES ('" . $psdb->escape($server['id']) . "', '" . $psdb->escape($date) . "', '" . $psdb->escape($usercount) . "') " . - "ON DUPLICATE KEY UPDATE `date`='" . $psdb->escape($date) . "', `usercount`='" . $psdb->escape($usercount) . "'"); - - if ($server['id'] === 'showdown') { - $psdb->query( - "INSERT INTO `ntbb_userstatshistory` (`date`, `usercount`) " . - "VALUES ('" . $psdb->escape($date) . "', '" . $psdb->escape($usercount) . "')"); - } - $dispatcher->setPrefix(''); // No need for prefix since only usable by server. - } - - public function updatenamecolor($dispatcher, &$reqData, &$out) { - global $psdb, $psconfig, $users; - $server = $dispatcher->findServer(); - if (!isset($psconfig['mainserver']) || !$server || $server['id'] !== $psconfig['mainserver']) { - $out['actionerror'] = 'Access denied'; - return; - } - if (!isset($reqData['userid']) || !mb_strlen($users->userid($reqData['userid']))) { - $out['actionerror'] = 'No userid was specified.'; - return; - } - $userid = $users->userid($reqData['userid']); - if (!isset($reqData['source'])) { - $out['actionerror'] = 'No color adjustment was specified.'; - return; - } - if (strlen($userid) > 18) { - $out['actionerror'] = 'Usernames can only be 18 characters long'; - return; - } - if (!isset($reqData['by']) || !mb_strlen($users->userid($reqData['by']))) { - $out['actionerror'] = 'Specify the action\'s actor.'; - return; - } - $colors = array(); - $path = realpath(__DIR__ . '/../config/colors.json'); - try { - $data = file_get_contents($path, true); - $colors = json_decode($data, true); - } catch (Exception $e) {} - $modlog_entry = ''; - if (!$reqData['source']) { - if (!isset($colors[$userid])) { - $out['actionerror'] = ( - 'That user does not have a custom color set by the loginserver. ' . - 'Ask an admin to remove it manually if they have one.' - ); - return; - } else { - unset($colors[$userid]); - $modlog_entry = 'Username color was removed'; - } - } else { - $colors[$userid] = $reqData['source']; - $modlog_entry = "Username color was set to \"{$reqData['source']}\""; - } - file_put_contents($path, json_encode($colors)); - - $psdb->query( - "INSERT INTO `{$psdb->prefix}usermodlog`". - "(`userid`, `actorid`, `date`, `ip`, `entry`) " . - "VALUES(?, ?, ?, ?, ?)", - [$userid, $users->userid($reqData['by']), time(), $dispatcher->getIp(), $modlog_entry] - ); - - $out['success'] = true; - return $out; - } - - public function prepreplay($dispatcher, &$reqData, &$out) { - global $psdb, $users; - // include_once dirname(__FILE__) . '/ntbb-ladder.lib.php'; // not clear if this is needed - - $server = $dispatcher->findServer(); - if (!$server) { - $out['errorip'] = $dispatcher->getIp(); - return; - } - if ( - // the server must be registered - !$server || - // the server must send all the required values - !isset($reqData['id']) || - !isset($reqData['format']) || - !isset($reqData['loghash']) || - !isset($reqData['p1']) || - !isset($reqData['p2']) || - // player usernames cannot be longer than 18 characters - (mb_strlen($reqData['p1']) > 18) || - (mb_strlen($reqData['p2']) > 18) || - // the battle ID must be valid - !preg_match('/^([a-z0-9]+)-[0-9]+$/', $reqData['id'], $m1) || - // the format ID must be valid - !preg_match('/^([a-z0-9]+)$/', $reqData['format'], $m2) || - // the format from the battle ID must match the format ID - ($m1[1] !== $m2[1])) { - $out = 0; - return; - } - - if ($server['id'] !== 'showdown') { - $reqData['id'] = $server['id'].'-'.$reqData['id']; - } - $reqData['serverid'] = $server['id']; - - include_once __DIR__.'/../replays/replays.lib.php'; - $out = $GLOBALS['Replays']->prepUpload($reqData); - - $dispatcher->setPrefix(''); // No need for prefix since only usable by server. - } - - public function uploadreplay($dispatcher, &$reqData, &$out) { - global $psdb, $users; - - header('Content-Type: text/plain; charset=utf-8'); - - include __DIR__.'/../replays/replays.lib.php'; - die($GLOBALS['Replays']->upload($reqData)); - } - - public function invalidatecss($dispatcher, &$reqData, &$out) { - $server = $dispatcher->findServer(); - if (!$server) { - $out['errorip'] = $dispatcher->getIp(); - return; - } - // No need to sanitise $server['id'] because it should be safe already. - $cssfile = __DIR__ . '/../config/customcss/' . $server['id'] . '.css'; - @unlink($cssfile); - } -} - -// This class should not depend on ntbb-session.lib.php. -class LadderActionHandler { - // There's no need to make a database query for this. - private function getUserData($username) { - if (!$username) $username = ''; - $userid = strtr($username, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"); - $userid = preg_replace('/[^A-Za-z0-9]+/', '', $userid); - if (mb_strlen($userid) > 18) return false; - return array('userid' => $userid, 'username' => $username); - } - - public function ladderupdate($dispatcher, &$reqData, &$out) { - include_once dirname(__FILE__) . '/ntbb-ladder.lib.php'; - - $server = $dispatcher->findServer(); - if (!$server || $server['id'] !== 'showdown') { - $out['errorip'] = "Your version of PS is too old for this ladder system. Please update."; - return; - } - - $ladder = new NTBBLadder(@$reqData['format']); - $p1 = $this->getUserData(@$reqData['p1']); - $p2 = $this->getUserData(@$reqData['p2']); - if (!$p1 || !$p2) { - // The server should not send usernames > 18 characters long. - $out = 0; - return; - } - - $ladder->updateRating($p1, $p2, floatval($reqData['score'])); - $out['actionsuccess'] = true; - $out['p1rating'] = $p1['rating']; - $out['p2rating'] = $p2['rating']; - unset($out['p1rating']['rpdata']); - unset($out['p2rating']['rpdata']); - $dispatcher->setPrefix(''); // No need for prefix since only usable by server. - } - - public function ladderget($dispatcher, &$reqData, &$out) { - global $PokemonServers; - include_once dirname(__FILE__) . '/ntbb-ladder.lib.php'; - - $server = @$PokemonServers[@$reqData['serverid']]; - if (!$server || $server['id'] !== 'showdown') { - die; - } - - $ladder = new NTBBLadder(@$reqData['format']); - $user = $this->getUserData(@$reqData['user']); - if (!$user) die; - $ladder->getAllRatings($user); - $out = $user['ratings']; - } - - public function mmr($dispatcher, &$reqData, &$out) { - global $PokemonServers; - include_once dirname(__FILE__) . '/ntbb-ladder.lib.php'; - - $server = $dispatcher->findServer(); - if (!$server || $server['id'] !== 'showdown') { - $out['errorip'] = "Your version of PS is too old for this ladder system. Please update."; - return; - } - - $ladder = new NTBBLadder(@$reqData['format']); - $user = $this->getUserData(@$reqData['user']); - $out = 1000; - if ($user) { - $ladder->getRating($user); - if (@$user['rating']) { - $out = intval($user['rating']['elo']); - } - } - } -} diff --git a/old-replays/.htaccess b/old-replays/.htaccess deleted file mode 100644 index 0473bb21f5..0000000000 --- a/old-replays/.htaccess +++ /dev/null @@ -1,40 +0,0 @@ -# -FrontPage- - -IndexIgnore .htaccess */.??* *~ *# */HEADER* */README* */_vti* - - -order deny,allow -deny from all -allow from all - - -order deny,allow -deny from all - - -AddType text/plain .phps -AddType application/x-tgz .tgz -AddType application/x-chrome-extension .crx -AddType application/x-web-app-manifest+json .webapp - - -RewriteEngine on - -RewriteCond %{HTTP:X-Forwarded-Proto} ^http$ -RewriteRule ^(.*)$ https://replay.pokemonshowdown.com/$1 [R=302,NE,L] - -RewriteRule ^replay\/(.*)$ /$1 [R=302,L] - -RewriteRule ^battle-([A-Za-z0-9-]+)?$ /$1 [R=302,L] - -RewriteRule ^search/?$ search.php [L,QSA] -RewriteRule ^search\.json$ search.json.php [L,QSA] -RewriteRule ^([A-Za-z0-9-]+)$ battle.php?name=$1 [L,QSA] -RewriteRule ^([A-Za-z0-9-]+)/manage$ battle.php?name=$1&manage [L,QSA] -RewriteRule ^([A-Za-z0-9-]+)\.log$ battle.log.php?name=$1 [L,QSA] -RewriteRule ^([A-Za-z0-9-]+)\.json$ battle.log.php?json&name=$1 [L,QSA] - -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^(apple-touch-icon-precomposed\.png)$ - [R=404,L] - - diff --git a/old-replays/404.php b/old-replays/404.php deleted file mode 100644 index d6f99c92b3..0000000000 --- a/old-replays/404.php +++ /dev/null @@ -1,46 +0,0 @@ -setPageTitle("Replay not found"); -$panels->noScripts(); -$panels->start(); - -?> -
    -
    - -

    Not Found

    -

    - The battle you're looking for has expired. Battles expire after 15 minutes of inactivity unless they're saved. -

    -

    - In the future, remember to click Upload and share replay to save a replay permanently. -

    - - - - -
    -
    -end(); - -?> diff --git a/old-replays/503.php b/old-replays/503.php deleted file mode 100644 index 723f865be2..0000000000 --- a/old-replays/503.php +++ /dev/null @@ -1,43 +0,0 @@ -setPageTitle("Replay not found"); -$panels->noScripts(); -$panels->start(); - -?> -
    -
    - -

    Technical difficulties

    -

    - offlineReason ? $Replays->offlineReason : "We're currently experiencing some technical difficulties. Please try again later. Sorry." ?> -

    - - - - -
    -
    -end(); - -?> diff --git a/old-replays/apple-touch-icon.png b/old-replays/apple-touch-icon.png deleted file mode 100644 index bfff1b75c5929e6a147712035ef225dc2e511854..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45373 zcmcF~WmgU4pwMxH}9M+=9CXcL>25ToN?6L$DBBg9O*$u7Sbbb"Jnwt& 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 diff --git a/old-replays/build b/old-replays/build deleted file mode 100755 index b58d8a99e3..0000000000 --- a/old-replays/build +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env node - -/** - * This script parses index.html and sets the version query string of each - * resource to be the MD5 hash of that resource. - */ - -const fs = require('fs'); -const crypto = require('crypto'); - -process.chdir(__dirname); - -function updateIndex() { - let indexContents = fs.readFileSync('theme/wrapper.inc.template.php', {encoding: 'utf8'}); - - // add hashes to js and css files - process.stdout.write("Updating hashes... "); - // Check for ]+?src|]+?href|]+?src)="\/(.*?)(\?[a-z0-9]*?)?"/g, runReplace); - console.log("DONE"); - - process.stdout.write("Writing new `wrapper.inc.php` file... "); - fs.writeFileSync('theme/wrapper.inc.php', indexContents); - console.log("DONE"); -} - -function runReplace(a, b, c) { - let hash = Math.random(); // just in case creating the hash fails - const routes = JSON.parse(fs.readFileSync('../config/routes.json')); - try { - var filepath = c; - if (c.includes('/' + routes.client + '/')) { - const filename = c.replace('/' + routes.client + '/', ''); - filepath = '../' + filename; - } - const fstr = fs.readFileSync(filepath, {encoding: 'utf8'}); - hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8); - } catch (e) {} - c = c.replace('/replay.pokemonshowdown.com/', '/' + routes.replays + '/'); - c = c.replace('/dex.pokemonshowdown.com/', '/' + routes.dex + '/'); - c = c.replace('/play.pokemonshowdown.com/', '/' + routes.client + '/'); - c = c.replace('/pokemonshowdown.com/users/', '/' + routes.users + '/'); - c = c.replace('/pokemonshowdown.com/', '/' + routes.root + '/'); - - return b + '="/' + c + '?' + hash + '"'; -} - -updateIndex(); diff --git a/old-replays/favicon.ico b/old-replays/favicon.ico deleted file mode 100644 index 34b1536b185990d18a6d143df6526eaf88c35898..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 zcmZQzU<5(|0RaXO&|qX>5ChRb3=&ZQVnzlQAj!bc045;>L^T7$ijGvUz}NRL8CK-! zGbB37GrYdK4@o6{rXUu;zyJ~yQc?{7(JC%ZAX>=T*hCRT8!JI*B^46|ki3wy5k#G_ zk`g13uWY2^1g4FR!L*REF~lGxrBJX!K|vS|RQ>-y0|OZIGcf!B;txRlKpu)=V(dV1 RDE`6B!0-o%{~w0v0|1VuEFS;> diff --git a/old-replays/index.php b/old-replays/index.php deleted file mode 100644 index 8aba3a5286..0000000000 --- a/old-replays/index.php +++ /dev/null @@ -1,246 +0,0 @@ -setPageTitle('Replays'); -$panels->setPageDescription('Watch replays of battles on Pokémon Showdown!'); -$panels->setTab('replay'); -$panels->start(); -?> -
    -

    Upload replays

    -

    - To upload a replay, click "Share" or use the command /savereplay in a Pokémon Showdown battle! -

    -

    Search replays

    - -
    -

    - - -

    - -
    -

    - - -

    - -

    Featured replays

    - -

    Recent replays

    - -
    - -end(); - -?> diff --git a/old-replays/js/ou-305002749.log b/old-replays/js/ou-305002749.log deleted file mode 100644 index 0bb335583f..0000000000 --- a/old-replays/js/ou-305002749.log +++ /dev/null @@ -1,14927 +0,0 @@ -|j|CHEF BOY4RDEEZNUTS -|player|p1|CHEF BOY4RDEEZNUTS|203 -|player|p2|Crime♥|146 -|gametype|singles -|gen|6 -|tier|OU -|rated -|seed|51607,1132,42462,64155 -|clearpoke -|poke|p1|Sableye, M -|poke|p1|Tentacruel, M -|poke|p1|Gliscor, M -|poke|p1|Chansey, F -|poke|p1|Jirachi -|poke|p1|Clefable, M -|poke|p2|Chansey, F -|poke|p2|Skarmory, F -|poke|p2|Heatran, F, shiny -|poke|p2|Florges, F -|poke|p2|Cobalion -|poke|p2|Slowbro, F -|rule|Swagger Clause: Swagger is banned -|rule|Baton Pass Clause: Limit one Baton Passer, can't pass Spe and other stats simultaneously -|rule|Sleep Clause Mod: Limit one foe put to sleep -|rule|Species Clause: Limit one of each Pokémon -|rule|OHKO Clause: OHKO moves are banned -|rule|Moody Clause: Moody is banned -|rule|Evasion Moves Clause: Evasion moves are banned -|rule|Endless Battle Clause: Forcing endless battles is banned -|rule|HP Percentage Mod: HP is shown in percentages -|teampreview -|c|★Crime♥|nice stall -|c|★Crime♥|<3 -|choice|team 5|team 3 -| -|start -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Heatran|Heatran, F, shiny|386/386 -|turn|1 -|c|★Crime♥|im not good at stall yet ;3 -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Heatran -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Heatran|Stealth Rock|p1a: TheMoreYouKnow -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|turn|2 -|c|★CHEF BOY4RDEEZNUTS|its a fun play style -|c|★Crime♥|yes haha -|c|★Crime♥|people get so mad! -|c|★CHEF BOY4RDEEZNUTS|alot of ppl hate it when you use it tho -|c|★Crime♥|XD -|choice|move 2|move 1 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Heatran -|-status|p2a: Heatran|par -|cant|p2a: Heatran|par -| -|turn|3 -|c|★Crime♥|its called playing defensive.. -|c|★Crime♥|with healers and tanks -|choice|move 3|move 1 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|372/386 par -|choice|switch 2| -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -|move|p2a: Heatran|Lava Plume|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-crit|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|262/363 -|-status|p1a: U Jelly Bruh?|brn -| -|-heal|p1a: U Jelly Bruh?|284/363 brn|[from] item: Black Sludge -|-heal|p2a: Heatran|386/386 par|[from] item: Leftovers -|-damage|p1a: U Jelly Bruh?|239/363 brn|[from] brn -|turn|4 -|c|★Crime♥|you jelly bruhhhhhhhhhh -|c|★Crime♥|:3 -|choice|move 4|switch 4 -| -|switch|p2a: Florges|Florges, F|360/360 -|-damage|p2a: Florges|315/360|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Florges -|-damage|p2a: Florges|308/360 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|261/363 brn|[from] item: Black Sludge -|-heal|p2a: Florges|330/360|[from] item: Leftovers -|-damage|p1a: U Jelly Bruh?|216/363 brn|[from] brn -|turn|5 -|choice|switch 4|move 3 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Florges|Aromatherapy|p2a: Florges -|-cureteam|p2a: Florges|[from] move: Aromatherapy -| -|-heal|p2a: Florges|352/360|[from] item: Leftovers -|turn|6 -|choice|move 4|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|334/334 -|-damage|p2a: Skarmory|293/334|[from] Stealth Rock -|move|p1a: Fatty|Heal Bell|p1a: Fatty -|-cureteam|p1a: Fatty|[from] move: HealBell -| -|turn|7 -|choice|switch 5|move 3 -| -|switch|p1a: I <3 Stall|Sableye, M|301/301 -|move|p2a: Skarmory|Defog|p1a: I <3 Stall -|-unboost|p1a: I <3 Stall|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|8 -|c|★Crime♥|should i replace cobalion -|c|★CHEF BOY4RDEEZNUTS|idk ive never seen one on a stall team -|c|★Crime♥|haha -|choice|move 2 mega|switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|detailschange|p1a: I <3 Stall|Sableye-Mega, M -|-mega|p1a: I <3 Stall|Sableye|Sablenite -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|9 -|choice|move 2|move 1 -| -|move|p2a: Slowbro|Scald|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|243/301 -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|10 -|choice|move 1|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|386/386 -|move|p1a: I <3 Stall|Shadow Ball|p2a: Heatran -|-damage|p2a: Heatran|253/386 -| -|-heal|p2a: Heatran|277/386|[from] item: Leftovers -|turn|11 -|choice|move 1|move 1 -| -|move|p2a: Heatran|Lava Plume|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|189/301 -|move|p1a: I <3 Stall|Shadow Ball|p2a: Heatran -|-damage|p2a: Heatran|139/386 -| -|-heal|p2a: Heatran|163/386|[from] item: Leftovers -|turn|12 -|choice|move 4|switch 3 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -| -|turn|13 -|choice|move 2|move 4 -| -|move|p2a: Chansey|Wish|p2a: Chansey -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|14 -|choice|move 2|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|163/386 -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|-heal|p2a: Heatran|386/386|[from] move: Wish|[wisher] Chansey -|turn|15 -|choice|move 2|move 1 -| -|move|p2a: Heatran|Lava Plume|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|265/301 -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|16 -|choice|move 1|move 1 -| -|move|p2a: Heatran|Lava Plume|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|237/301 -|-status|p1a: I <3 Stall|brn -|move|p1a: I <3 Stall|Shadow Ball|p2a: Heatran -|-damage|p2a: Heatran|149/386 -| -|-heal|p2a: Heatran|173/386|[from] item: Leftovers -|-damage|p1a: I <3 Stall|200/301 brn|[from] brn -|turn|17 -|choice|move 4|switch 3 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 brn -| -|-damage|p1a: I <3 Stall|264/301 brn|[from] brn -|turn|18 -|choice|switch 2|move 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Wish|p2a: Chansey -| -|turn|19 -|choice|move 2|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|173/386 -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Heatran -|-status|p2a: Heatran|par -| -|-heal|p2a: Heatran|386/386 par|[from] move: Wish|[wisher] Chansey -|turn|20 -|choice|move 3|move 4 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|373/386 par -|choice|switch 5| -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Heatran|Taunt|p1a: Fatty -|-start|p1a: Fatty|move: Taunt -| -|-heal|p2a: Heatran|386/386 par|[from] item: Leftovers -|turn|21 -|choice|move 1|move 3 -| -|move|p1a: Fatty|Seismic Toss|p2a: Heatran -|-damage|p2a: Heatran|286/386 par -|move|p2a: Heatran|Stealth Rock|p1a: Fatty -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|310/386 par|[from] item: Leftovers -|turn|22 -|choice|move 1|switch 3 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|move|p1a: Fatty|Seismic Toss|p2a: Chansey -|-damage|p2a: Chansey|542/642 -| -|-end|p1a: Fatty|move: Taunt -|turn|23 -|choice|move 4|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|310/386 par -|move|p1a: Fatty|Heal Bell|p1a: Fatty -|-cureteam|p1a: Fatty|[from] move: HealBell -| -|-heal|p2a: Heatran|334/386 par|[from] item: Leftovers -|turn|24 -|choice|move 3|move 4 -| -|move|p1a: Fatty|Wish|p1a: Fatty -|move|p2a: Heatran|Taunt|p1a: Fatty -|-start|p1a: Fatty|move: Taunt -| -|-heal|p2a: Heatran|358/386 par|[from] item: Leftovers -|turn|25 -|choice|switch 4|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|216/363 -|-damage|p1a: U Jelly Bruh?|171/363|[from] Stealth Rock -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|-damage|p1a: I <3 Stall|227/301|[from] Stealth Rock -| -|-heal|p1a: I <3 Stall|301/301|[from] move: Wish|[wisher] Fatty -|-heal|p2a: Heatran|382/386 par|[from] item: Leftovers -|turn|26 -|choice|move 1|move 1 -| -|move|p1a: I <3 Stall|Shadow Ball|p2a: Heatran -|-damage|p2a: Heatran|316/386 par -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|340/386 par|[from] item: Leftovers -|turn|27 -|choice|switch 2|move 1 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|171/363 -|-damage|p1a: U Jelly Bruh?|126/363|[from] Stealth Rock -|move|p2a: Heatran|Lava Plume|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|89/363 -| -|-heal|p1a: U Jelly Bruh?|111/363|[from] item: Black Sludge -|-heal|p2a: Heatran|364/386 par|[from] item: Leftovers -|turn|28 -|choice|move 4|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|387/394 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|133/363|[from] item: Black Sludge -|turn|29 -|choice|switch 4|move 1 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Slowbro|Scald|p1a: Fatty -|-crit|p1a: Fatty -|-damage|p1a: Fatty|575/642 -| -|turn|30 -|choice|move 2|switch 3 -| -|switch|p2a: Chansey|Chansey, F|542/642 -|move|p1a: Fatty|Toxic|p2a: Chansey -|-status|p2a: Chansey|tox -| -|-damage|p2a: Chansey|502/642 tox|[from] psn -|turn|31 -|c|★Crime♥|do you get high in rating with ur stall team? -|c|★CHEF BOY4RDEEZNUTS|not super high but decent -|c|★Crime♥|oh -|c|★Crime♥|i got to 1650 max -|c|★CHEF BOY4RDEEZNUTS|i have good streaks and bad streaks lol -|choice|switch 4|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|133/363 -|move|p2a: Chansey|Toxic|p1a: U Jelly Bruh? -|-immune|p1a: U Jelly Bruh?|[msg] -| -|-heal|p1a: U Jelly Bruh?|155/363|[from] item: Black Sludge -|-damage|p2a: Chansey|422/642 tox|[from] psn -|turn|32 -|c|★Crime♥|yes -|choice|move 3|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|344/394 -| -|-heal|p1a: U Jelly Bruh?|177/363|[from] item: Black Sludge -|turn|33 -|choice|switch 5|move 1 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Slowbro|Scald|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|312/403 -| -|-heal|p1a: TheMoreYouKnow|337/403|[from] item: Leftovers -|turn|34 -|choice|move 2|switch 3 -| -|switch|p2a: Chansey|Chansey, F|422/642 -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Chansey -|-status|p2a: Chansey|par -| -|-heal|p1a: TheMoreYouKnow|362/403|[from] item: Leftovers -|turn|35 -|choice|move 1|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|293/334 -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|261/334 -| -|-heal|p1a: TheMoreYouKnow|387/403|[from] item: Leftovers -|turn|36 -|choice|switch 2|switch 6 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Chansey|Chansey, F|422/642 -| -|turn|37 -|choice|switch 5|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|177/363 -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|642/642 -| -|-heal|p1a: U Jelly Bruh?|199/363|[from] item: Black Sludge -|turn|38 -|c|★Crime♥|imagine -|c|★Crime♥|if we time stall this -|c|★Crime♥|XD -|choice|move 3|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|344/394 -| -|-heal|p1a: U Jelly Bruh?|221/363|[from] item: Black Sludge -|turn|39 -|choice|switch 4|move 1 -| -|switch|p1a: Fatty|Chansey, F|575/642 -|move|p2a: Slowbro|Scald|p1a: Fatty -|-damage|p1a: Fatty|527/642 -| -|turn|40 -|choice|move 1|switch 3 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|move|p1a: Fatty|Seismic Toss|p2a: Chansey -|-damage|p2a: Chansey|542/642 -| -|turn|41 -|choice|switch 2|move 1 -| -|switch|p1a: TheMoreYouKnow|Jirachi|387/403 -|move|p2a: Chansey|Seismic Toss|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|287/403 -| -|-heal|p1a: TheMoreYouKnow|312/403|[from] item: Leftovers -|turn|42 -|choice|move 4|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|261/334 -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|337/403|[from] item: Leftovers -|turn|43 -|choice|move 2|move 3 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Skarmory -|-status|p2a: Skarmory|par -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|-heal|p1a: TheMoreYouKnow|362/403|[from] item: Leftovers -|turn|44 -|choice|move 4|move 2 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|334/334 par -| -|-heal|p1a: TheMoreYouKnow|387/403|[from] item: Leftovers -|turn|45 -|choice|move 1|move 3 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|300/334 par -|cant|p2a: Skarmory|flinch -| -|-heal|p1a: TheMoreYouKnow|403/403|[from] item: Leftovers -|turn|46 -|choice|move 1|move 3 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|266/334 par -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|47 -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|move 4|move 1 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|cant|p2a: Skarmory|par -| -|turn|48 -|c|★Crime♥|:P -|choice|move 1|move 3 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|235/334 par -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|49 -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|50 -|c|★Crime♥|lmao -|c|★Crime♥|this game -|c|★Crime♥|XD -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|cant|p2a: Skarmory|par -| -|turn|51 -|choice|switch 6|move 3 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|move|p2a: Skarmory|Defog|p1a: Redbull -|-unboost|p1a: Redbull|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|52 -|c|★Crime♥|no rocks! -|choice|move 2|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|364/386 par -|move|p1a: Redbull|Flamethrower|p2a: Heatran -|-start|p2a: Heatran|ability: Flash Fire -| -|-heal|p2a: Heatran|386/386 par|[from] item: Leftovers -|turn|53 -|c|★CHEF BOY4RDEEZNUTS|guess it was obvious eh -|choice|switch 2|move 1 -| -|switch|p1a: Fatty|Chansey, F|527/642 -|cant|p2a: Heatran|par -| -|turn|54 -|choice|move 3|move 1 -| -|move|p1a: Fatty|Wish|p1a: Fatty -|move|p2a: Heatran|Lava Plume|p1a: Fatty -|-crit|p1a: Fatty -|-damage|p1a: Fatty|386/642 -| -|turn|55 -|choice|move 1|move 2 -| -|move|p1a: Fatty|Seismic Toss|p2a: Heatran -|-damage|p2a: Heatran|286/386 par -|cant|p2a: Heatran|par -| -|-heal|p1a: Fatty|642/642|[from] move: Wish|[wisher] Fatty -|-heal|p2a: Heatran|310/386 par|[from] item: Leftovers -|turn|56 -|choice|move 1|move 4 -| -|move|p1a: Fatty|Seismic Toss|p2a: Heatran -|-damage|p2a: Heatran|210/386 par -|move|p2a: Heatran|Taunt|p1a: Fatty -|-start|p1a: Fatty|move: Taunt -| -|-heal|p2a: Heatran|234/386 par|[from] item: Leftovers -|turn|57 -|choice|move 1|switch 6 -| -|-end|p2a: Heatran|ability: Flash Fire|[silent] -|switch|p2a: Chansey|Chansey, F|542/642 -|move|p1a: Fatty|Seismic Toss|p2a: Chansey -|-damage|p2a: Chansey|442/642 -| -|turn|58 -|choice|switch 6|move 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Wish|p2a: Chansey -| -|turn|59 -|choice|move 4|switch 4 -| -|switch|p2a: Skarmory|Skarmory, F|235/334 par -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|-heal|p2a: Skarmory|334/334 par|[from] move: Wish|[wisher] Chansey -|turn|60 -|choice|move 3|move 3 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|324/334 par -|choice|switch 5| -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Skarmory|Defog|p1a: I <3 Stall -|move|p1a: I <3 Stall|Defog|p2a: Skarmory|[from]Magic Bounce -|-unboost|p2a: Skarmory|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|61 -|c|★Crime♥|!data cobalion -|c|~|/data-pokemon Cobalion - -|c|★Crime♥|look at that hp and defense.. -|c|★Crime♥|the type makes it perfect -|choice|move 2|switch 4 -| -|switch|p2a: Chansey|Chansey, F|442/642 -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|62 -|c|★CHEF BOY4RDEEZNUTS|i dont think ive ever used one -|choice|move 2|move 4 -| -|move|p2a: Chansey|Wish|p2a: Chansey -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|63 -|choice|move 1|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|234/386 par -|move|p1a: I <3 Stall|Shadow Ball|p2a: Heatran -|-damage|p2a: Heatran|107/386 par -|-unboost|p2a: Heatran|spd|1 -| -|-heal|p2a: Heatran|386/386 par|[from] move: Wish|[wisher] Chansey -|turn|64 -|choice|move 1|switch 6 -| -|switch|p2a: Chansey|Chansey, F|442/642 -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|65 -|choice|move 2|move 4 -| -|move|p2a: Chansey|Wish|p2a: Chansey -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|66 -|choice|move 2|move 1 -| -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|-heal|p2a: Chansey|642/642|[from] move: Wish|[wisher] Chansey -|turn|67 -|choice|move 3|switch 2 -| -|switch|p2a: Florges|Florges, F|352/360 -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Florges -|-status|p2a: Florges|brn -| -|-heal|p2a: Florges|360/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|315/360 brn|[from] brn -|turn|68 -|choice|move 1|move 3 -| -|move|p2a: Florges|Aromatherapy|p2a: Florges -|-cureteam|p2a: Florges|[from] move: Aromatherapy -|move|p1a: I <3 Stall|Shadow Ball|p2a: Florges -|-damage|p2a: Florges|188/360 -| -|-heal|p2a: Florges|210/360|[from] item: Leftovers -|turn|69 -|choice|switch 5|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Florges|Protect|p2a: Florges -|-fail|p2a: Florges -| -|-heal|p2a: Florges|232/360|[from] item: Leftovers -|turn|70 -|choice|move 2|switch 4 -| -|switch|p2a: Skarmory|Skarmory, F|324/334 -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Skarmory -|-status|p2a: Skarmory|par -| -|turn|71 -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|72 -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|73 -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|74 -|c|★Crime♥|lol -|c|★Crime♥|i might need 2x defoggers -|c|★Crime♥|in my team -|c|★Crime♥|XD -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|75 -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|76 -|c|★Crime♥|see -|c|★CHEF BOY4RDEEZNUTS|XD -|c|★Crime♥|thats how i lose -|c|★Crime♥|xD -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|77 -|choice|move 4|move 3 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|78 -|choice|move 1|move 3 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|291/334 par -|cant|p2a: Skarmory|flinch -| -|turn|79 -|choice|move 4|move 4 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|cant|p2a: Skarmory|par -| -|turn|80 -|choice|move 1|move 3 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|255/334 par -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|81 -|choice|move 4|move 4 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Skarmory -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Skarmory|Whirlwind|p1a: TheMoreYouKnow -|drag|p1a: Fatty|Chansey, F|642/642 -| -|turn|82 -|choice|move 1|move 3 -| -|move|p1a: Fatty|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|155/334 par -|move|p2a: Skarmory|Defog|p1a: Fatty -|-unboost|p1a: Fatty|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|83 -|choice|move 1|switch 2 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|move|p1a: Fatty|Seismic Toss|p2a: Chansey -|-damage|p2a: Chansey|542/642 -| -|turn|84 -|choice|switch 4|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|221/363 -|move|p2a: Chansey|Wish|p2a: Chansey -| -|-heal|p1a: U Jelly Bruh?|243/363|[from] item: Black Sludge -|turn|85 -|choice|move 3|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|155/334 par -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Skarmory -|-crit|p2a: Skarmory -|-damage|p2a: Skarmory|114/334 par -|-enditem|p2a: Skarmory|Shed Shell|[from] move: Knock Off|[of] p1a: U Jelly Bruh? -| -|-heal|p2a: Skarmory|334/334 par|[from] move: Wish|[wisher] Chansey -|-heal|p1a: U Jelly Bruh?|265/363|[from] item: Black Sludge -|turn|86 -|c|★Crime♥|doesnt matter lol -|c|★Crime♥|its for magnezone -|c|★CHEF BOY4RDEEZNUTS|yeah -|c|★Crime♥|XD -|choice|switch 6|switch 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Chansey|Chansey, F|542/642 -| -|turn|87 -|choice|move 1|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|386/386 -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|363/386 -| -|-heal|p2a: Heatran|386/386|[from] item: Leftovers -|turn|88 -|choice|switch 5|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Taunt|p1a: I <3 Stall -|move|p1a: I <3 Stall|Taunt|p2a: Heatran|[from]Magic Bounce -|-start|p2a: Heatran|move: Taunt -| -|turn|89 -|c|★Crime♥|please -|c|★Crime♥|;c -|choice|switch 4|switch 6 -| -|switch|p2a: Chansey|Chansey, F|542/642 -|switch|p1a: Fatty|Chansey, F|642/642 -| -|turn|90 -|c|★Crime♥|maybe i should get a bold clefable instead of cobalion -|c|★Crime♥|:P -|choice|switch 3|switch 2 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 -|switch|p2a: Skarmory|Skarmory, F|334/334 par -| -|-status|p1a: Annoying AF|tox|[from] item: Toxic Orb -|turn|91 -|c|★CHEF BOY4RDEEZNUTS|its come in handy numerous times -|choice|switch 4|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Skarmory|Brave Bird|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|229/301 -|-damage|p2a: Skarmory|310/334 par|[from] recoil|[of] p1a: I <3 Stall -| -|turn|92 -|c|★Crime♥|it tanks fight and dark right -|c|★CHEF BOY4RDEEZNUTS|yeah -|c|★Crime♥|how is fairy vs fairy -|c|★Crime♥|normal? -|choice|move 1|switch 2 -| -|switch|p2a: Chansey|Chansey, F|542/642 -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|93 -|choice|move 4|switch 4 -| -|switch|p2a: Florges|Florges, F|232/360 -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -| -|-heal|p2a: Florges|254/360|[from] item: Leftovers -|turn|94 -|c|★CHEF BOY4RDEEZNUTS|it depends on the fairy -|c|★CHEF BOY4RDEEZNUTS|like gard wrecks clef unless you alread have calm minds up -|choice|switch 5|switch 4 -| -|switch|p2a: Chansey|Chansey, F|542/642 -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|95 -|choice|move 4|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|386/386 -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Heatran -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|turn|96 -|c|★CHEF BOY4RDEEZNUTS|thats what my rachi is for :P -|c|★CHEF BOY4RDEEZNUTS|fairy counter -|c|★CHEF BOY4RDEEZNUTS|and the latis -|c|★Crime♥|oh oke -|choice|move 3|move 1 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|372/386 -|choice|switch 6| -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|265/363 -|move|p2a: Heatran|Lava Plume|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|227/363 -| -|-heal|p1a: U Jelly Bruh?|249/363|[from] item: Black Sludge -|-heal|p2a: Heatran|386/386|[from] item: Leftovers -|turn|97 -|choice|move 1|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|301/394 -| -|-heal|p1a: U Jelly Bruh?|271/363|[from] item: Black Sludge -|turn|98 -|choice|switch 3|move 1 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Slowbro|Scald|p1a: Fatty -|-damage|p1a: Fatty|596/642 -| -|turn|99 -|c|★Crime♥|how many turns will we reach? -|choice|move 1|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|310/334 par -|-damage|p2a: Skarmory|269/334 par|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|169/334 par -| -|turn|100 -|c|★CHEF BOY4RDEEZNUTS|200? lol -|choice|move 1|switch 6 -| -|switch|p2a: Chansey|Chansey, F|542/642 -|-damage|p2a: Chansey|462/642|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Chansey -|-damage|p2a: Chansey|362/642 -| -|turn|101 -|c|★Crime♥|yes i think -|choice|switch 6|move 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Wish|p2a: Chansey -| -|turn|102 -|choice|move 3|move 3 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Chansey -|-damage|p2a: Chansey|273/642 -|choice|switch 3| -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|271/363 -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|594/642 -| -|-heal|p2a: Chansey|642/642|[from] move: Wish|[wisher] Chansey -|-heal|p1a: U Jelly Bruh?|293/363|[from] item: Black Sludge -|turn|103 -|c|★Crime♥|this game wouldnt end with time stall -|choice|switch 3|switch 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -| -|turn|104 -|choice|move 3|switch 2 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|-damage|p2a: Chansey|562/642|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Chansey -|-damage|p2a: Chansey|464/642 -|choice|switch 3| -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|293/363 -| -|-heal|p1a: U Jelly Bruh?|315/363|[from] item: Black Sludge -|turn|105 -|choice|move 3|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|299/394 -| -|-heal|p1a: U Jelly Bruh?|337/363|[from] item: Black Sludge -|turn|106 -|c|★Crime♥|knock off my chansey huh? -|choice|switch 6|switch 2 -| -|switch|p1a: Fatty|Chansey, F|596/642 -|switch|p2a: Chansey|Chansey, F|464/642 -|-damage|p2a: Chansey|384/642|[from] Stealth Rock -| -|turn|107 -|c|★CHEF BOY4RDEEZNUTS|trying to lol -|c|★Crime♥|lol -|choice|switch 3|move 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|642/642 -| -|turn|108 -|c|★Crime♥|i need moves to get PP backk -|c|★Crime♥|XD -|choice|move 2|move 4 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Chansey -|-status|p2a: Chansey|par -|move|p2a: Chansey|Wish|p2a: Chansey -| -|turn|109 -|choice|move 2|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|169/334 par -|-damage|p2a: Skarmory|128/334 par|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Skarmory -|-fail|p2a: Skarmory|par -| -|-heal|p2a: Skarmory|334/334 par|[from] move: Wish|[wisher] Chansey -|turn|110 -|c|★CHEF BOY4RDEEZNUTS|derp -|choice|move 3|switch 6 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|-damage|p2a: Chansey|562/642|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Chansey -|-damage|p2a: Chansey|476/642 -|choice|switch 2| -| -|switch|p1a: Redbull|Clefable, M|393/393 -| -|turn|111 -|choice|move 4|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|386/386 -|-damage|p2a: Heatran|338/386|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|362/386|[from] item: Leftovers -|turn|112 -|choice|switch 6|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|337/363 -|move|p2a: Heatran|Stealth Rock|p1a: U Jelly Bruh? -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|359/363|[from] item: Black Sludge -|-heal|p2a: Heatran|386/386|[from] item: Leftovers -|turn|113 -|choice|move 4|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|337/394 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|turn|114 -|choice|move 1|switch 5 -| -|switch|p2a: Cobalion|Cobalion|386/386 -|-damage|p2a: Cobalion|374/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Cobalion -|-damage|p2a: Cobalion|272/386 -|-status|p2a: Cobalion|brn -|-enditem|p2a: Cobalion|Lum Berry|[eat] -|-curestatus|p2a: Cobalion|brn -| -|turn|115 -|c|★CHEF BOY4RDEEZNUTS|ooooo -|c|★Crime♥|lol -|choice|switch 4|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|292/352 tox -| -|-heal|p1a: Annoying AF|336/352 tox|[from] ability: Poison Heal -|turn|116 -|choice|move 1|move 2 -| -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|284/352 tox -|cant|p1a: Annoying AF|flinch -| -|-heal|p1a: Annoying AF|328/352 tox|[from] ability: Poison Heal -|turn|117 -|choice|move 1|move 3 -| -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -|move|p1a: Annoying AF|Earthquake|p2a: Cobalion -|-supereffective|p2a: Cobalion -|-damage|p2a: Cobalion|246/386 slp -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|118 -|c|★Crime♥|tanky right -|c|★Crime♥|:P -|c|★CHEF BOY4RDEEZNUTS|bulkier than i thought XD -|choice|move 3|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|334/334 par -|-damage|p2a: Skarmory|293/334 par|[from] Stealth Rock -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|264/352 tox -| -|-heal|p1a: Annoying AF|308/352 tox|[from] ability: Poison Heal -|turn|119 -|c|★Crime♥|lol -|choice|move 1|move 3 -| -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -|move|p2a: Skarmory|Defog|p1a: Annoying AF -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|120 -|choice|switch 2|switch 5 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Slowbro|Slowbro, F|394/394 -| -|turn|121 -|choice|move 4|move 1 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Slowbro -|-sidestart|p2: Crime♥|move: Stealth Rock -|move|p2a: Slowbro|Scald|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|313/403 -| -|-heal|p1a: TheMoreYouKnow|338/403|[from] item: Leftovers -|turn|122 -|choice|move 2|switch 3 -| -|switch|p2a: Chansey|Chansey, F|476/642 -|-damage|p2a: Chansey|396/642|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Chansey -|-status|p2a: Chansey|par -| -|-heal|p1a: TheMoreYouKnow|363/403|[from] item: Leftovers -|turn|123 -|choice|move 1|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|293/334 par -|-damage|p2a: Skarmory|252/334 par|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|216/334 par -| -|-heal|p1a: TheMoreYouKnow|388/403|[from] item: Leftovers -|turn|124 -|choice|move 1|move 2 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|181/334 par -|cant|p2a: Skarmory|flinch -| -|-heal|p1a: TheMoreYouKnow|403/403|[from] item: Leftovers -|turn|125 -|choice|move 1|switch 6 -| -|switch|p2a: Cobalion|Cobalion|246/386 slp -|-damage|p2a: Cobalion|234/386 slp|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|199/386 slp -| -|turn|126 -|c|★Crime♥|3% dmg from rocks -|c|★Crime♥|so good -|choice|move 3|move 3 -| -|cant|p2a: Cobalion|slp -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|189/386 slp -|choice|switch 2| -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|turn|127 -|choice|switch 2|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|181/334 par -|-damage|p2a: Skarmory|140/334 par|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|128 -|choice|move 1|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|306/394 -| -|turn|129 -|choice|move 3|switch 3 -| -|switch|p2a: Skarmory|Skarmory, F|140/334 par -|-damage|p2a: Skarmory|99/334 par|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|90/334 par -|choice|switch 6| -| -|switch|p1a: Redbull|Clefable, M|393/393 -| -|turn|130 -|choice|switch 2|switch 2 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|switch|p2a: Heatran|Heatran, F, shiny|386/386 -|-damage|p2a: Heatran|338/386|[from] Stealth Rock -| -|-heal|p2a: Heatran|362/386|[from] item: Leftovers -|turn|131 -|c|★Crime♥|lmao -|choice|move 1|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|90/334 par -|-damage|p2a: Skarmory|49/334 par|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|132 -|choice|switch 4|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|216/334 par -| -|turn|133 -|c|★CHEF BOY4RDEEZNUTS|nooooooooo lol -|choice|move 1|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|298/394 -| -|turn|134 -|choice|switch 3|move 3 -| -|switch|p1a: Fatty|Chansey, F|596/642 -|move|p2a: Slowbro|Toxic|p1a: Fatty -|-status|p1a: Fatty|tox -| -|-damage|p1a: Fatty|556/642 tox|[from] psn -|turn|135 -|choice|move 2|switch 4 -| -|switch|p2a: Florges|Florges, F|254/360 -|-damage|p2a: Florges|209/360|[from] Stealth Rock -|move|p1a: Fatty|Toxic|p2a: Florges -|-status|p2a: Florges|tox -| -|-heal|p2a: Florges|231/360 tox|[from] item: Leftovers -|-damage|p2a: Florges|209/360 tox|[from] psn -|-damage|p1a: Fatty|476/642 tox|[from] psn -|turn|136 -|choice|move 2|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Fatty|Toxic|p2a: Florges|[miss] -|-miss|p1a: Fatty|p2a: Florges -| -|-heal|p2a: Florges|231/360 tox|[from] item: Leftovers -|-damage|p2a: Florges|187/360 tox|[from] psn -|-damage|p1a: Fatty|356/642 tox|[from] psn -|turn|137 -|choice|move 4|move 1 -| -|move|p2a: Florges|Moonblast|p1a: Fatty -|-damage|p1a: Fatty|296/642 tox -|move|p1a: Fatty|Heal Bell|p1a: Fatty -|-cureteam|p1a: Fatty|[from] move: HealBell -| -|-heal|p2a: Florges|360/360 tox|[from] move: Wish|[wisher] Florges -|-damage|p2a: Florges|294/360 tox|[from] psn -|turn|138 -|choice|move 3|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Fatty|Wish|p1a: Fatty -| -|-heal|p2a: Florges|316/360 tox|[from] item: Leftovers -|-damage|p2a: Florges|228/360 tox|[from] psn -|turn|139 -|choice|move 1|switch 6 -| -|switch|p2a: Cobalion|Cobalion|189/386 slp -|-damage|p2a: Cobalion|177/386 slp|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Cobalion -|-damage|p2a: Cobalion|77/386 slp -| -|-heal|p2a: Cobalion|257/386 slp|[from] move: Wish|[wisher] Florges -|-heal|p1a: Fatty|617/642|[from] move: Wish|[wisher] Fatty -|turn|140 -|c|★Crime♥|welcome back to life -|c|★Crime♥|;c -|choice|switch 4|switch 5 -| -|switch|p2a: Chansey|Chansey, F|396/642 -|-damage|p2a: Chansey|316/642|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 -| -|-status|p1a: Annoying AF|tox|[from] item: Toxic Orb -|turn|141 -|choice|move 1|switch 3 -| -|switch|p2a: Skarmory|Skarmory, F|216/334 par -|-damage|p2a: Skarmory|175/334 par|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|142 -|choice|switch 6|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|cant|p2a: Skarmory|par -| -|turn|143 -|choice|move 2|move 2 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Skarmory -|-fail|p2a: Skarmory|par -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|334/334 par -| -|turn|144 -|choice|move 3|switch 5 -| -|switch|p2a: Cobalion|Cobalion|257/386 slp -|-damage|p2a: Cobalion|245/386 slp|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-crit|p2a: Cobalion -|-damage|p2a: Cobalion|231/386 slp -|c|★Crime♥|4% crit -|c|★Crime♥|op -|choice|switch 6| -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|turn|145 -|choice|switch 6|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|334/334 par -|-damage|p2a: Skarmory|293/334 par|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|146 -|choice|move 1|switch 5 -| -|switch|p2a: Cobalion|Cobalion|231/386 slp -|-damage|p2a: Cobalion|219/386 slp|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|186/386 slp -| -|turn|147 -|choice|move 3|move 3 -| -|cant|p2a: Cobalion|slp -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|176/386 slp -|c| Team Delta Ethan|bruh -|c|★Crime♥|lol -|choice|switch 6| -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|turn|148 -|c|★Crime♥|boring battle -|c|★Crime♥|but we are talking so -|c|★Crime♥|:P -|choice|move 1|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|293/334 par -|-damage|p2a: Skarmory|252/334 par|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|149 -|c|★CHEF BOY4RDEEZNUTS|150 turns no mons dead lol -|c|★Crime♥|XD -|choice|switch 5|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Skarmory|Whirlwind|p1a: I <3 Stall -|move|p1a: I <3 Stall|Whirlwind|p2a: Skarmory|[from]Magic Bounce -|drag|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -| -|turn|150 -|c|★Crime♥|weeeeeeeeeeee -|c|★Crime♥|lmao -|choice|move 1|switch 3 -| -|switch|p2a: Chansey|Chansey, F|316/642 -|-damage|p2a: Chansey|236/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|151 -|choice|switch 2|move 3 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|557/642 -| -|turn|152 -|choice|move 4|switch 2 -| -|switch|p2a: Heatran|Heatran, F, shiny|362/386 -|-damage|p2a: Heatran|314/386|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|338/386|[from] item: Leftovers -|turn|153 -|choice|switch 3|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Stealth Rock|p1a: U Jelly Bruh? -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|362/386|[from] item: Leftovers -|turn|154 -|choice|move 4|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|337/394 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|turn|155 -|choice|move 3|move 2 -| -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-singleturn|p2a: Slowbro|Protect -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-activate|p2a: Slowbro|Protect -| -|turn|156 -|c|★Crime♥|protect slowbro -|c|★Crime♥|XDDDDDDDDD -|choice|switch 6|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|turn|157 -|choice|move 3|switch 2 -| -|switch|p2a: Chansey|Chansey, F|557/642 -|-damage|p2a: Chansey|477/642|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Chansey -|-damage|p2a: Chansey|389/642 -|choice|switch 2| -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|turn|158 -|choice|move 2|move 3 -| -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|642/642 -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|159 -|choice|move 1|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|362/386 -|-damage|p2a: Heatran|314/386|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Heatran -|-damage|p2a: Heatran|208/386 -| -|-heal|p2a: Heatran|232/386|[from] item: Leftovers -|turn|160 -|choice|move 2|switch 3 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|-damage|p2a: Chansey|562/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|161 -|c|★Crime♥|omg -|c|★Crime♥|my -|c|★Crime♥|family -|c|★Crime♥|is so fucked up in the head -|c|★Crime♥|seriously -|c|★CHEF BOY4RDEEZNUTS|wat? -|c|★Crime♥|especially in the mornings -|c|★Crime♥|just screaming like idiots in the morning -|c|★Crime♥|and blaming me all day -|choice|move 1|move 1 -| -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|162 -|choice|move 2|move 1 -| -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|163 -|choice|move 3|move 4 -| -|move|p2a: Chansey|Wish|p2a: Chansey -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|482/642 brn|[from] brn -|turn|164 -|choice|move 1|switch 6 -| -|switch|p2a: Florges|Florges, F|228/360 tox -|-damage|p2a: Florges|183/360 tox|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Florges -|-damage|p2a: Florges|71/360 tox -| -|-heal|p2a: Florges|360/360 tox|[from] move: Wish|[wisher] Chansey -|-damage|p2a: Florges|338/360 tox|[from] psn -|turn|165 -|c|★Crime♥|phew -|choice|switch 6|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Florges|Aromatherapy|p2a: Florges -|-cureteam|p2a: Florges|[from] move: Aromatherapy -| -|-heal|p2a: Florges|360/360|[from] item: Leftovers -|turn|166 -|choice|move 2|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|296/394 -|-unboost|p2a: Slowbro|spd|2 -| -|turn|167 -|choice|move 2|move 2 -| -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-singleturn|p2a: Slowbro|Protect -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-activate|p2a: Slowbro|Protect -| -|turn|168 -|choice|move 3|switch 5 -| -|switch|p2a: Cobalion|Cobalion|176/386 -|-damage|p2a: Cobalion|164/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|154/386 -|-ability|p2a: Cobalion|Justified|boost -|-boost|p2a: Cobalion|atk|1 -| -|turn|169 -|choice|switch 5|move 3 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|turn|170 -|c|★Crime♥|XD -|c|★Crime♥|rest# -|choice|switch 6|switch 4 -| -|switch|p2a: Skarmory|Skarmory, F|252/334 -|-damage|p2a: Skarmory|211/334|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|turn|171 -|c|★Crime♥|will we get to turn 300 -|choice|move 2|switch 6 -| -|switch|p2a: Chansey|Chansey, F|482/642 -|-damage|p2a: Chansey|402/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|172 -|choice|switch 2|switch 4 -| -|switch|p2a: Cobalion|Cobalion|386/386 slp -|-damage|p2a: Cobalion|374/386 slp|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|173 -|choice|move 3|move 4 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|365/386 slp -|choice|switch 6| -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|cant|p2a: Cobalion|slp -| -|turn|174 -|choice|move 1|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|211/334 -|-damage|p2a: Skarmory|170/334|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|175 -|c|★CHEF BOY4RDEEZNUTS|at this rate yes -|choice|move 1|move 2 -| -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|334/334 -| -|turn|176 -|choice|switch 2|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Skarmory|Whirlwind|p1a: I <3 Stall -|move|p1a: I <3 Stall|Whirlwind|p2a: Skarmory|[from]Magic Bounce -|drag|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -| -|turn|177 -|choice|move 1|switch 2 -| -|switch|p2a: Florges|Florges, F|360/360 -|-damage|p2a: Florges|315/360|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Florges -|-damage|p2a: Florges|267/360 -|-unboost|p2a: Florges|spd|1 -| -|-heal|p2a: Florges|289/360|[from] item: Leftovers -|turn|178 -|c|★Crime♥|im gonna change my playstyle -|choice|switch 5|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Florges|Wish|p2a: Florges -| -|-heal|p2a: Florges|311/360|[from] item: Leftovers -|turn|179 -|c| Bambi22|plz -|c| Team Delta Ethan|>:( -|choice|move 3|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Florges -|-activate|p2a: Florges|Protect -| -|-heal|p2a: Florges|360/360|[from] move: Wish|[wisher] Florges -|turn|180 -|c|★CHEF BOY4RDEEZNUTS|lol -|c|★Crime♥|no -|c|★Crime♥|im running out of pp -|c|★Crime♥|:P -|c|★Crime♥|im losing -|c| Team Delta Ethan|I FUCKING HATE PHABLE -|c| Team Delta Ethan|HE SUCKS -|choice|move 3|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|299/394 -| -|turn|181 -|choice|move 2|move 1 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|253/394 -|-unboost|p2a: Slowbro|spd|2 -|move|p2a: Slowbro|Scald|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|333/363 -|-status|p1a: U Jelly Bruh?|brn -| -|-heal|p1a: U Jelly Bruh?|355/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|310/363 brn|[from] brn -|turn|182 -|c| Bambi22|ok -|c|★Crime♥|and please run out of knock off -|c|★Crime♥|llol -|choice|move 1|switch 6 -| -|switch|p2a: Cobalion|Cobalion|365/386 slp -|-damage|p2a: Cobalion|353/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Cobalion -|-damage|p2a: Cobalion|254/386 slp -| -|-heal|p1a: U Jelly Bruh?|332/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|287/363 brn|[from] brn -|turn|183 -|choice|switch 2|switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|384/394 -|-damage|p2a: Slowbro|335/394|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|turn|184 -|choice|move 2|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|334/334 -|-damage|p2a: Skarmory|293/334|[from] Stealth Rock -|move|p1a: Annoying AF|Toxic|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|185 -|c|★Crime♥|annoying AF! -|c| Bambi22|do you not have a water move on tentacruel -|choice|switch 6|switch 5 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -| -|turn|186 -|c|★Crime♥|lmao -|c|★Crime♥|no scald tenta -|c|★Crime♥|op -|choice|move 3|switch 6 -| -|switch|p2a: Cobalion|Cobalion|254/386 slp -|-damage|p2a: Cobalion|242/386 slp|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-crit|p2a: Cobalion -|-damage|p2a: Cobalion|227/386 slp -|c|★CHEF BOY4RDEEZNUTS|it has scald -|c| Bambi22|oh wait i thought crime had the gliscor -|c| Bambi22|my bad -|choice|switch 3| -| -|switch|p1a: Redbull|Clefable, M|393/393 -| -|turn|187 -|c|★Crime♥|i really need weed for this battle -|c|★Crime♥|haha -|choice|switch 6|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|232/386 -|-damage|p2a: Heatran|184/386|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-heal|p2a: Heatran|208/386|[from] item: Leftovers -|turn|188 -|choice|move 1|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|293/334 -|-damage|p2a: Skarmory|252/334|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|189 -|choice|switch 3|move 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Skarmory|Whirlwind|p1a: TheMoreYouKnow -|drag|p1a: Fatty|Chansey, F|617/642 -| -|turn|190 -|choice|move 4|move 4 -| -|move|p1a: Fatty|Heal Bell|p1a: Fatty -|-cureteam|p1a: Fatty|[from] move: HealBell -|move|p2a: Skarmory|Whirlwind|p1a: Fatty -|drag|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|turn|191 -|choice|move 3|move 4 -| -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Skarmory -|-status|p2a: Skarmory|brn -|move|p2a: Skarmory|Whirlwind|p1a: I <3 Stall -|move|p1a: I <3 Stall|Whirlwind|p2a: Skarmory|[from]Magic Bounce -|drag|p2a: Chansey|Chansey, F|402/642 -|-damage|p2a: Chansey|322/642|[from] Stealth Rock -| -|turn|192 -|choice|switch 2|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|287/363 -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|642/642 -| -|-heal|p1a: U Jelly Bruh?|309/363|[from] item: Black Sludge -|turn|193 -|choice|move 1|switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|300/394 -|-status|p2a: Slowbro|brn -| -|-heal|p1a: U Jelly Bruh?|331/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|251/394 brn|[from] brn -|turn|194 -|choice|move 1|move 4 -| -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|202/394 brn -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 brn -| -|-heal|p1a: U Jelly Bruh?|353/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|345/394 brn|[from] brn -|turn|195 -|c|★CHEF BOY4RDEEZNUTS|yup knew it -|choice|move 2|move 1 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|296/394 brn -|-unboost|p2a: Slowbro|spd|2 -|move|p2a: Slowbro|Scald|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|323/363 -| -|-heal|p1a: U Jelly Bruh?|345/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|247/394 brn|[from] brn -|turn|196 -|c|★Crime♥|lol -|c|★Crime♥|ofcourse i have slack off -|c|★Crime♥|XD -|choice|move 1|move 4 -| -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|153/394 brn -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|350/394 brn -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|301/394 brn|[from] brn -|turn|197 -|choice|move 2|move 1 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|213/394 brn -|-unboost|p2a: Slowbro|spd|2 -|move|p2a: Slowbro|Scald|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|333/363 -| -|-heal|p1a: U Jelly Bruh?|355/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|164/394 brn|[from] brn -|turn|198 -|choice|move 1|move 4 -| -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|29/394 brn -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|226/394 brn -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|177/394 brn|[from] brn -|turn|199 -|c| Bambi22|and this is only in the 1400s on the ladder? -|c|★Crime♥|yes around -|c|★CHEF BOY4RDEEZNUTS|im at 1420 -|c|★CHEF BOY4RDEEZNUTS|currently -|c| Team Delta Ethan|this annoys me -|choice|move 1|switch 2 -| -|switch|p2a: Florges|Florges, F|360/360 -|-damage|p2a: Florges|315/360|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Florges -|-damage|p2a: Florges|267/360 -|-status|p2a: Florges|brn -| -|-heal|p2a: Florges|289/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|244/360 brn|[from] brn -|turn|200 -|c| Team Delta Ethan|i hate tank battles -|choice|move 2|move 4 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Florges -|-supereffective|p2a: Florges -|-crit|p2a: Florges -|-damage|p2a: Florges|178/360 brn -|-unboost|p2a: Florges|spd|2 -|move|p2a: Florges|Wish|p2a: Florges -| -|-heal|p2a: Florges|200/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|155/360 brn|[from] brn -|turn|201 -|c|★CHEF BOY4RDEEZNUTS|incoming protect -|c| Bambi22|where are the stallbreakers at? -|choice|move 1|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: U Jelly Bruh?|Scald|p2a: Florges -|-activate|p2a: Florges|Protect -| -|-heal|p2a: Florges|335/360 brn|[from] move: Wish|[wisher] Florges -|-heal|p2a: Florges|357/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|312/360 brn|[from] brn -|turn|202 -|choice|move 2|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|308/394 brn -|-damage|p2a: Slowbro|259/394 brn|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|216/394 brn -|-unboost|p2a: Slowbro|spd|2 -| -|-damage|p2a: Slowbro|167/394 brn|[from] brn -|turn|203 -|choice|move 2|move 4 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|70/394 brn -|-unboost|p2a: Slowbro|spd|2 -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|267/394 brn -| -|-damage|p2a: Slowbro|218/394 brn|[from] brn -|turn|204 -|choice|move 2|switch 2 -| -|switch|p2a: Florges|Florges, F|312/360 brn -|-damage|p2a: Florges|267/360 brn|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Florges -|-supereffective|p2a: Florges -|-damage|p2a: Florges|225/360 brn -|-unboost|p2a: Florges|spd|2 -| -|-heal|p2a: Florges|247/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|202/360 brn|[from] brn -|turn|205 -|choice|move 2|move 3 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Florges -|-supereffective|p2a: Florges -|-damage|p2a: Florges|118/360 brn -|-unboost|p2a: Florges|spd|2 -|move|p2a: Florges|Aromatherapy|p2a: Florges -|-cureteam|p2a: Florges|[from] move: Aromatherapy -| -|-heal|p2a: Florges|140/360|[from] item: Leftovers -|turn|206 -|choice|move 2|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Florges -|-activate|p2a: Florges|Protect -| -|-heal|p2a: Florges|162/360|[from] item: Leftovers -|turn|207 -|choice|move 2|switch 3 -| -|switch|p2a: Cobalion|Cobalion|227/386 -|-damage|p2a: Cobalion|215/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Cobalion -|-immune|p2a: Cobalion|[msg] -| -|turn|208 -|choice|move 1|move 3 -| -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -|move|p1a: U Jelly Bruh?|Scald|p2a: Cobalion -|-damage|p2a: Cobalion|278/386 slp -| -|turn|209 -|c|★CHEF BOY4RDEEZNUTS|ugh -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|move 1|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|349/394 -|-damage|p2a: Slowbro|300/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-crit|p2a: Slowbro -|-damage|p2a: Slowbro|232/394 -| -|turn|210 -|c|★Crime♥|lol -|choice|move 2|move 4 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|183/394 -|-unboost|p2a: Slowbro|spd|2 -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|380/394 -| -|turn|211 -|c|★Crime♥|!data acid spray -|c|~|/data-move Acid Spray - -|choice|move 2|move 1 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|284/394 -|-unboost|p2a: Slowbro|spd|2 -|move|p2a: Slowbro|Scald|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|336/363 -| -|-heal|p1a: U Jelly Bruh?|358/363|[from] item: Black Sludge -|turn|212 -|c| Bambi22|this is the definition of pp stall -|c|★CHEF BOY4RDEEZNUTS|useful for against calm mind clef -|c|★CHEF BOY4RDEEZNUTS|acid spray -|choice|move 2|switch 2 -| -|switch|p2a: Cobalion|Cobalion|278/386 slp -|-damage|p2a: Cobalion|266/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Cobalion -|-immune|p2a: Cobalion|[msg] -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|turn|213 -|choice|move 1|switch 3 -| -|switch|p2a: Florges|Florges, F|162/360 -|-damage|p2a: Florges|117/360|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Florges -|-damage|p2a: Florges|72/360 -|-status|p2a: Florges|brn -| -|-heal|p2a: Florges|94/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|49/360 brn|[from] brn -|turn|214 -|c|★Crime♥|nooo -|c|★CHEF BOY4RDEEZNUTS|yussss -|c| Bambi22|and there it is. -|choice|move 2|move 3 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Florges -|-supereffective|p2a: Florges -|-damage|p2a: Florges|7/360 brn -|-unboost|p2a: Florges|spd|2 -|move|p2a: Florges|Aromatherapy|p2a: Florges -|-cureteam|p2a: Florges|[from] move: Aromatherapy -| -|-heal|p2a: Florges|29/360|[from] item: Leftovers -|turn|215 -|c|★Crime♥|lol -|choice|move 2|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Florges -|-activate|p2a: Florges|Protect -| -|-heal|p2a: Florges|51/360|[from] item: Leftovers -|turn|216 -|c|★CHEF BOY4RDEEZNUTS|sighhhhh -|c| Bambi22|or not -|choice|move 2|switch 4 -| -|switch|p2a: Skarmory|Skarmory, F|252/334 -|-damage|p2a: Skarmory|211/334|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|217 -|c|★CHEF BOY4RDEEZNUTS|no more aromatherapy at least -|choice|move 1|move 2 -| -|move|p1a: U Jelly Bruh?|Scald|p2a: Skarmory -|-damage|p2a: Skarmory|115/334 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|282/334 -| -|turn|218 -|choice|move 1|move 3 -| -|move|p1a: U Jelly Bruh?|Scald|p2a: Skarmory -|-damage|p2a: Skarmory|174/334 -|move|p2a: Skarmory|Defog|p1a: U Jelly Bruh? -|-unboost|p1a: U Jelly Bruh?|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|219 -|c|★Crime♥|oh -|c|★Crime♥|i has enough -|c|★Crime♥|aroma -|c|★Crime♥|:P -|c|★Crime♥|for another 200 turns -|choice|move 1|switch 6 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|move|p1a: U Jelly Bruh?|Scald|p2a: Chansey -|-damage|p2a: Chansey|597/642 -| -|turn|220 -|c|★CHEF BOY4RDEEZNUTS|u wont get a chance to use it -|c|★CHEF BOY4RDEEZNUTS|tho -|choice|move 3|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|342/394 -| -|turn|221 -|choice|switch 5|move 1 -| -|switch|p1a: Fatty|Chansey, F|617/642 -|move|p2a: Slowbro|Scald|p1a: Fatty -|-damage|p1a: Fatty|568/642 -| -|turn|222 -|choice|move 2|switch 2 -| -|switch|p2a: Chansey|Chansey, F|597/642 -|move|p1a: Fatty|Toxic|p2a: Chansey -|-status|p2a: Chansey|tox -| -|-damage|p2a: Chansey|557/642 tox|[from] psn -|turn|223 -|choice|switch 4|move 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Wish|p2a: Chansey -| -|-damage|p2a: Chansey|477/642 tox|[from] psn -|turn|224 -|choice|move 1|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|174/334 -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|138/334 -| -|-heal|p2a: Skarmory|334/334|[from] move: Wish|[wisher] Chansey -|turn|225 -|choice|move 4|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|208/386 -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Heatran -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|-heal|p2a: Heatran|232/386|[from] item: Leftovers -|turn|226 -|choice|move 2|move 3 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Heatran -|-status|p2a: Heatran|par -|move|p2a: Heatran|Stealth Rock|p1a: TheMoreYouKnow -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|turn|227 -|choice|move 3|move 2 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|242/386 par -|choice|switch 5| -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -|cant|p2a: Heatran|par -| -|-heal|p1a: U Jelly Bruh?|340/363|[from] item: Black Sludge -|-heal|p2a: Heatran|266/386 par|[from] item: Leftovers -|turn|228 -|c| Bambi22|maybe run scarf rachi with fire punch? -|choice|move 4|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|338/394 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|362/363|[from] item: Black Sludge -|turn|229 -|choice|switch 4|move 1 -| -|switch|p1a: Fatty|Chansey, F|568/642 -|move|p2a: Slowbro|Scald|p1a: Fatty -|-damage|p1a: Fatty|516/642 -| -|turn|230 -|choice|move 2|switch 3 -| -|switch|p2a: Cobalion|Cobalion|266/386 -|-damage|p2a: Cobalion|254/386|[from] Stealth Rock -|move|p1a: Fatty|Toxic|p2a: Cobalion -|-immune|p2a: Cobalion|[msg] -| -|turn|231 -|choice|switch 2|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Cobalion|[from]Magic Bounce -|drag|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -| -|turn|232 -|choice|move 1|switch 6 -| -|switch|p2a: Chansey|Chansey, F|477/642 -|-damage|p2a: Chansey|397/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|233 -|choice|move 2|move 4 -| -|move|p2a: Chansey|Wish|p2a: Chansey -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|234 -|choice|move 2|switch 2 -| -|switch|p2a: Heatran|Heatran, F, shiny|266/386 par -|-damage|p2a: Heatran|218/386 par|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|-heal|p2a: Heatran|386/386 par|[from] move: Wish|[wisher] Chansey -|turn|235 -|choice|move 1|switch 2 -| -|switch|p2a: Chansey|Chansey, F|397/642 -|-damage|p2a: Chansey|317/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|236 -|choice|switch 5|move 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|638/642 -| -|turn|237 -|c|★Crime♥|lmao -|choice|move 2|switch 3 -| -|switch|p2a: Cobalion|Cobalion|254/386 -|-damage|p2a: Cobalion|242/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Cobalion -|-status|p2a: Cobalion|par -| -|turn|238 -|choice|move 1|move 3 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|204/386 par -|cant|p2a: Cobalion|par -| -|turn|239 -|choice|move 1|move 3 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|170/386 par -|cant|p2a: Cobalion|flinch -| -|turn|240 -|c|★Crime♥|opls -|choice|move 1|move 3 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|135/386 par -|cant|p2a: Cobalion|flinch -| -|turn|241 -|c|★Crime♥|pls -|choice|move 1|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|334/334 -|-damage|p2a: Skarmory|293/334|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|260/334 -| -|turn|242 -|choice|switch 4|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|362/363 -|move|p2a: Skarmory|Defog|p1a: U Jelly Bruh? -|-unboost|p1a: U Jelly Bruh?|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|turn|243 -|choice|move 1|switch 3 -| -|switch|p2a: Chansey|Chansey, F|638/642 -|move|p1a: U Jelly Bruh?|Scald|p2a: Chansey -|-damage|p2a: Chansey|599/642 -| -|turn|244 -|choice|move 2|switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|349/394 -|-unboost|p2a: Slowbro|spd|2 -| -|turn|245 -|choice|move 1|switch 6 -| -|switch|p2a: Chansey|Chansey, F|599/642 -|move|p1a: U Jelly Bruh?|Scald|p2a: Chansey -|-damage|p2a: Chansey|557/642 -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|477/642 brn|[from] brn -|turn|246 -|choice|switch 6|switch 6 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|switch|p2a: Slowbro|Slowbro, F|394/394 -| -|turn|247 -|c|★Crime♥|maybe turn 400? -|c|★CHEF BOY4RDEEZNUTS|oh god lol -|choice|move 1|switch 2 -| -|switch|p2a: Heatran|Heatran, F, shiny|386/386 par -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|364/386 par -|-unboost|p2a: Heatran|spa|1 -| -|-heal|p2a: Heatran|386/386 par|[from] item: Leftovers -|turn|248 -|c|★Crime♥|i want to break down my record -|choice|switch 5|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Stealth Rock|p1a: I <3 Stall -|move|p1a: I <3 Stall|Stealth Rock|p2a: Heatran|[from]Magic Bounce -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|turn|249 -|choice|switch 3|move 1 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 -|move|p2a: Heatran|Lava Plume|p1a: Annoying AF -|-damage|p1a: Annoying AF|250/352 -| -|-status|p1a: Annoying AF|tox|[from] item: Toxic Orb -|turn|250 -|choice|move 1|switch 3 -| -|switch|p2a: Skarmory|Skarmory, F|260/334 -|-damage|p2a: Skarmory|219/334|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|-heal|p1a: Annoying AF|294/352 tox|[from] ability: Poison Heal -|turn|251 -|choice|switch 4|move 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|252 -|choice|move 4|switch 4 -| -|switch|p2a: Florges|Florges, F|51/360 -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Florges -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|-heal|p2a: Florges|73/360|[from] item: Leftovers -|turn|253 -|choice|move 1|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Florges -|-activate|p2a: Florges|Protect -| -|-heal|p2a: Florges|95/360|[from] item: Leftovers -|turn|254 -|c|★Crime♥|welcome back to life -|c|★Crime♥|florges -|choice|move 1|switch 4 -| -|switch|p2a: Skarmory|Skarmory, F|219/334 -|-damage|p2a: Skarmory|178/334|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|141/334 -| -|turn|255 -|choice|move 1|move 2 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|106/334 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|273/334 -| -|turn|256 -|choice|move 2|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Slowbro -|-status|p2a: Slowbro|par -| -|turn|257 -|choice|move 3|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|273/334 -|-damage|p2a: Skarmory|232/334|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|222/334 -|choice|switch 2| -| -|switch|p1a: Fatty|Chansey, F|516/642 -| -|turn|258 -|choice|move 1|move 4 -| -|move|p1a: Fatty|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|122/334 -|move|p2a: Skarmory|Whirlwind|p1a: Fatty -|drag|p1a: Annoying AF|Gliscor, M|294/352 tox -| -|-heal|p1a: Annoying AF|338/352 tox|[from] ability: Poison Heal -|turn|259 -|choice|switch 4|move 2 -| -|switch|p1a: Fatty|Chansey, F|516/642 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|289/334 -| -|turn|260 -|choice|move 1|switch 6 -| -|switch|p2a: Chansey|Chansey, F|477/642 -|-damage|p2a: Chansey|397/642|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Chansey -|-damage|p2a: Chansey|297/642 -| -|turn|261 -|choice|switch 5|move 3 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|618/642 -| -|turn|262 -|choice|move 4|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|386/386 par -|-damage|p2a: Heatran|338/386 par|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|362/386 par|[from] item: Leftovers -|turn|263 -|c|★Crime♥|omg -|c|★Crime♥|i need a smoke -|c|★Crime♥|LOL -|choice|move 4|move 3 -| -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|386/386 par|[from] item: Leftovers -|turn|264 -|c|★CHEF BOY4RDEEZNUTS|i mean you could always forfeit lol -|choice|move 4|move 2 -| -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -|move|p2a: Heatran|Roar|p1a: Redbull -|drag|p1a: Fatty|Chansey, F|516/642 -| -|turn|265 -|c|★Crime♥|lol -|choice|move 1|move 3 -| -|move|p1a: Fatty|Seismic Toss|p2a: Heatran -|-damage|p2a: Heatran|286/386 par -|move|p2a: Heatran|Stealth Rock|p1a: Fatty -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|310/386 par|[from] item: Leftovers -|turn|266 -|choice|switch 6|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: TheMoreYouKnow|Jirachi|403/403 -|-damage|p1a: TheMoreYouKnow|378/403|[from] Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|403/403|[from] item: Leftovers -|-heal|p2a: Heatran|334/386 par|[from] item: Leftovers -|turn|267 -|c|★CHEF BOY4RDEEZNUTS|we're literally going to struggle to the death -|choice|move 3|move 2 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|320/386 par -|c|★Crime♥|lmao -|choice|switch 4| -| -|switch|p1a: Annoying AF|Gliscor, M|338/352 tox -|-damage|p1a: Annoying AF|294/352 tox|[from] Stealth Rock -|move|p2a: Heatran|Roar|p1a: Annoying AF -|drag|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|-damage|p1a: I <3 Stall|264/301|[from] Stealth Rock -| -|-heal|p2a: Heatran|344/386 par|[from] item: Leftovers -|turn|268 -|choice|switch 2|switch 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|318/363 -|-damage|p1a: U Jelly Bruh?|273/363|[from] Stealth Rock -|switch|p2a: Chansey|Chansey, F|618/642 -|-damage|p2a: Chansey|538/642|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|295/363|[from] item: Black Sludge -|turn|269 -|choice|move 4|switch 5 -| -|switch|p2a: Cobalion|Cobalion|135/386 par -|-damage|p2a: Cobalion|123/386 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|120/386 par -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|317/363|[from] item: Black Sludge -|turn|270 -|c|★CHEF BOY4RDEEZNUTS|can jelly do it? -|choice|move 1|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 par -|-damage|p2a: Slowbro|345/394 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|301/394 par -| -|-heal|p1a: U Jelly Bruh?|339/363|[from] item: Black Sludge -|turn|271 -|c|★Crime♥|not risking that -|choice|move 2|move 1 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|249/394 par -|-unboost|p2a: Slowbro|spd|2 -|cant|p2a: Slowbro|par -| -|-heal|p1a: U Jelly Bruh?|361/363|[from] item: Black Sludge -|turn|272 -|choice|move 3|move 4 -| -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|197/394 par -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 par -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|turn|273 -|choice|move 2|move 2 -| -|cant|p2a: Slowbro|par -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|307/394 par -|-unboost|p2a: Slowbro|spd|2 -| -|turn|274 -|choice|move 2|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|344/386 par -|-damage|p2a: Heatran|296/386 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Heatran -|-immune|p2a: Heatran|[msg] -| -|-heal|p2a: Heatran|320/386 par|[from] item: Leftovers -|turn|275 -|choice|move 3|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 par -|-damage|p2a: Slowbro|345/394 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|301/394 par -| -|turn|276 -|choice|move 2|move 1 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|256/394 par -|-unboost|p2a: Slowbro|spd|2 -|cant|p2a: Slowbro|par -| -|turn|277 -|choice|move 3|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|289/334 -|-damage|p2a: Skarmory|248/334|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Skarmory -|-crit|p2a: Skarmory -|-damage|p2a: Skarmory|219/334 -| -|turn|278 -|choice|move 1|switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|387/394 par -|-damage|p2a: Slowbro|338/394 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|293/394 par -| -|turn|279 -|c|★Crime♥|lol -|c|★Crime♥|crazy battle -|choice|switch 4|switch 6 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Skarmory|Skarmory, F|219/334 -|-damage|p2a: Skarmory|178/334|[from] Stealth Rock -| -|turn|280 -|choice|move 3|move 2 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|168/334 -|choice|switch 5| -| -|switch|p1a: Redbull|Clefable, M|393/393 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|334/334 -| -|turn|281 -|choice|move 2|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|320/386 par -|-damage|p2a: Heatran|272/386 par|[from] Stealth Rock -|move|p1a: Redbull|Flamethrower|p2a: Heatran -|-start|p2a: Heatran|ability: Flash Fire -| -|-heal|p2a: Heatran|296/386 par|[from] item: Leftovers -|turn|282 -|c|★Crime♥|no defog -|c|★Crime♥|;c -|choice|switch 4|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: I <3 Stall|Sableye-Mega, M|264/301 -| -|-heal|p2a: Heatran|320/386 par|[from] item: Leftovers -|turn|283 -|choice|switch 2|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: Annoying AF|Gliscor, M|294/352 tox -| -|-heal|p2a: Heatran|344/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|338/352 tox|[from] ability: Poison Heal -|turn|284 -|c|★Crime♥|lol -|c| Bambi22|predicted -|choice|move 1|switch 3 -| -|-end|p2a: Heatran|ability: Flash Fire|[silent] -|switch|p2a: Skarmory|Skarmory, F|334/334 -|-damage|p2a: Skarmory|293/334|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|285 -|choice|switch 5|move 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Skarmory|Whirlwind|p1a: TheMoreYouKnow -|drag|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|turn|286 -|choice|move 4|switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 par -|-damage|p2a: Slowbro|345/394 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|336/394 par -| -|turn|287 -|c|★CHEF BOY4RDEEZNUTS|gotta save dat pp -|choice|switch 6|move 1 -| -|switch|p1a: Fatty|Chansey, F|516/642 -|move|p2a: Slowbro|Scald|p1a: Fatty -|-damage|p1a: Fatty|464/642 -| -|turn|288 -|choice|move 3|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|293/334 -|-damage|p2a: Skarmory|252/334|[from] Stealth Rock -|move|p1a: Fatty|Wish|p1a: Fatty -| -|turn|289 -|choice|switch 2|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Skarmory|Whirlwind|p1a: I <3 Stall -|move|p1a: I <3 Stall|Whirlwind|p2a: Skarmory|[from]Magic Bounce -|drag|p2a: Chansey|Chansey, F|538/642 -|-damage|p2a: Chansey|458/642|[from] Stealth Rock -| -|-heal|p1a: I <3 Stall|301/301|[from] move: Wish|[wisher] Fatty -|turn|290 -|c| Bambi22|someone save a replay of this when it's done -|c|★CHEF BOY4RDEEZNUTS|almost 300 turns no kills good lord -|choice|switch 3|move 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Wish|p2a: Chansey -| -|turn|291 -|c|★Crime♥|lol -|choice|move 3|switch 2 -| -|switch|p2a: Cobalion|Cobalion|120/386 par -|-damage|p2a: Cobalion|108/386 par|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|97/386 par -|choice|switch 5| -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-heal|p2a: Cobalion|386/386 par|[from] move: Wish|[wisher] Chansey -|turn|292 -|choice|switch 4|switch 5 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|switch|p2a: Skarmory|Skarmory, F|252/334 -|-damage|p2a: Skarmory|211/334|[from] Stealth Rock -| -|turn|293 -|choice|move 4|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|344/386 par -|-damage|p2a: Heatran|296/386 par|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|320/386 par|[from] item: Leftovers -|turn|294 -|choice|move 1|move 3 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|287/386 par -|move|p2a: Heatran|Stealth Rock|p1a: Redbull -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|311/386 par|[from] item: Leftovers -|turn|295 -|choice|move 1|move 2 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-crit|p2a: Heatran -|-damage|p2a: Heatran|262/386 par -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|286/386 par|[from] item: Leftovers -|turn|296 -|choice|move 1|move 4 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|256/386 par -|move|p2a: Heatran|Taunt|p1a: Redbull -|-start|p1a: Redbull|move: Taunt -| -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|297 -|choice|move 1|move 2 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|250/386 par -|move|p2a: Heatran|Roar|p1a: Redbull -|drag|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|340/363|[from] item: Black Sludge -|-heal|p2a: Heatran|274/386 par|[from] item: Leftovers -|turn|298 -|c|★CHEF BOY4RDEEZNUTS|theres the roar -|choice|move 4|switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 par -|-damage|p2a: Slowbro|345/394 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|337/394 par -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|362/363|[from] item: Black Sludge -|turn|299 -|choice|switch 2|move 2 -| -|switch|p1a: Fatty|Chansey, F|464/642 -|cant|p2a: Slowbro|par -| -|turn|300 -|c|★CHEF BOY4RDEEZNUTS|that para is saving your pp -|choice|move 3|switch 3 -| -|switch|p2a: Skarmory|Skarmory, F|211/334 -|-damage|p2a: Skarmory|170/334|[from] Stealth Rock -|move|p1a: Fatty|Wish|p1a: Fatty -| -|turn|301 -|choice|move 1|move 2 -| -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|334/334 -|move|p1a: Fatty|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|234/334 -| -|-heal|p1a: Fatty|642/642|[from] move: Wish|[wisher] Fatty -|turn|302 -|c|★Crime♥|yeah -|c|★Crime♥|lol -|choice|move 1|move 3 -| -|move|p2a: Skarmory|Defog|p1a: Fatty -|-unboost|p1a: Fatty|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -|move|p1a: Fatty|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|134/334 -| -|turn|303 -|choice|move 1|move 2 -| -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|301/334 -|move|p1a: Fatty|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|201/334 -| -|turn|304 -|c|★Crime♥|sec -|c|★CHEF BOY4RDEEZNUTS|ok -|choice|move 1|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 par -|move|p1a: Fatty|Seismic Toss|p2a: Slowbro -|-damage|p2a: Slowbro|294/394 par -| -|turn|305 -|choice|switch 5|switch 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Skarmory|Skarmory, F|201/334 -| -|turn|306 -|choice|move 4|switch 4 -| -|switch|p2a: Florges|Florges, F|95/360 -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Florges -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|-heal|p2a: Florges|117/360|[from] item: Leftovers -|turn|307 -|choice|move 2|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Florges -|-activate|p2a: Florges|Protect -| -|-heal|p2a: Florges|139/360|[from] item: Leftovers -|turn|308 -|choice|move 2|switch 5 -| -|switch|p2a: Cobalion|Cobalion|386/386 par -|-damage|p2a: Cobalion|374/386 par|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Cobalion -|-fail|p2a: Cobalion|par -| -|turn|309 -|choice|switch 4|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|cant|p2a: Cobalion|par -| -|turn|310 -|choice|switch 2|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|362/363 -|cant|p2a: Cobalion|par -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|turn|311 -|choice|move 1|move 4 -| -|move|p1a: U Jelly Bruh?|Scald|p2a: Cobalion -|-damage|p2a: Cobalion|266/386 par -|move|p2a: Cobalion|Roar|p1a: U Jelly Bruh? -|drag|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|312 -|choice|move 3|move 3 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|255/386 par -|choice|switch 2| -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|turn|313 -|c| lollity|hoooooly shit man -|c|★Crime♥|lol -|c|★CHEF BOY4RDEEZNUTS|i know lol -|choice|switch 6|switch 4 -| -|switch|p2a: Skarmory|Skarmory, F|201/334 -|-damage|p2a: Skarmory|160/334|[from] Stealth Rock -|switch|p1a: Redbull|Clefable, M|393/393 -| -|turn|314 -|choice|move 4|switch 2 -| -|switch|p2a: Chansey|Chansey, F|458/642 -|-damage|p2a: Chansey|378/642|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|turn|315 -|c| lollity|holy -|c| lollity|fucking shit -|choice|move 4|move 3 -| -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|642/642 -| -|turn|316 -|c| lollity|300 fucking turns -|choice|move 4|move 4 -| -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -|move|p2a: Chansey|Wish|p2a: Chansey -| -|turn|317 -|choice|move 4|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|274/386 par -|-damage|p2a: Heatran|226/386 par|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|386/386 par|[from] move: Wish|[wisher] Chansey -|turn|318 -|choice|move 1|move 2 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|320/386 par -|move|p2a: Heatran|Roar|p1a: Redbull -|drag|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|-heal|p2a: Heatran|344/386 par|[from] item: Leftovers -|turn|319 -|c|★Crime♥|there's the roar -|choice|move 3|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 par -|-damage|p2a: Slowbro|345/394 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|297/394 par -| -|turn|320 -|c| lollity|and everyone is like full hp -|c| lollity|this is going to struggle i guess -|choice|move 2|move 2 -| -|cant|p2a: Slowbro|par -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|252/394 par -|-unboost|p2a: Slowbro|spd|2 -| -|turn|321 -|c| Bambi22|cuz wish support, roost, etc. -|choice|move 2|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|344/386 par -|-damage|p2a: Heatran|296/386 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Heatran -|-immune|p2a: Heatran|[msg] -| -|-heal|p2a: Heatran|320/386 par|[from] item: Leftovers -|turn|322 -|choice|move 3|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|383/394 par -|-damage|p2a: Slowbro|334/394 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|282/394 par -| -|turn|323 -|c| lollity|you know -|c| lollity|yo could have won like 20 battles in this time -|choice|move 2|switch 4 -| -|switch|p2a: Cobalion|Cobalion|386/386 slp -|-damage|p2a: Cobalion|374/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Cobalion -|-immune|p2a: Cobalion|[msg] -| -|turn|324 -|c|★Crime♥|lol -|choice|switch 6|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|cant|p2a: Cobalion|slp -| -|turn|325 -|c|★CHEF BOY4RDEEZNUTS|shhhhhh lol -|c| tuxedo_cat|I have a rant against stalling for this. -|choice|switch 3|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|cant|p2a: Cobalion|slp -| -|turn|326 -|choice|move 2|move 2 -| -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Iron Head|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|246/301 -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|327 -|c| tuxedo_cat|Yeesh. -|choice|move 1|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|320/386 par -|-damage|p2a: Heatran|272/386 par|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Heatran -|-damage|p2a: Heatran|173/386 par -| -|-heal|p2a: Heatran|197/386 par|[from] item: Leftovers -|turn|328 -|c| tuxedo_cat|I hate the process, but I have to applaud you two. -|choice|move 3|switch 6 -| -|switch|p2a: Chansey|Chansey, F|642/642 -|-damage|p2a: Chansey|562/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|482/642 brn|[from] brn -|turn|329 -|choice|switch 2|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Toxic|p1a: TheMoreYouKnow -|-immune|p1a: TheMoreYouKnow|[msg] -| -|-damage|p2a: Chansey|402/642 brn|[from] brn -|turn|330 -|choice|move 1|switch 3 -| -|switch|p2a: Cobalion|Cobalion|374/386 -|-damage|p2a: Cobalion|362/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|326/386 -| -|turn|331 -|c| tuxedo_cat|How long have you two been here? -|c|★Crime♥|2 hours? -|c| tuxedo_cat|Yeesh! -|choice|move 2|move 4 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Cobalion -|-status|p2a: Cobalion|par -|move|p2a: Cobalion|Roar|p1a: TheMoreYouKnow -|drag|p1a: Redbull|Clefable, M|393/393 -| -|turn|332 -|c|★CHEF BOY4RDEEZNUTS|has it really been that long? -|c| tuxedo_cat|The highest I've ever gone was 93 moves. -|c|★Crime♥|lol 93.. -|c|★CHEF BOY4RDEEZNUTS|this is def my longest battle -|choice|move 4|switch 5 -| -|switch|p2a: Florges|Florges, F|139/360 -|-damage|p2a: Florges|94/360|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Florges|116/360|[from] item: Leftovers -|turn|333 -|choice|move 1|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Redbull|Moonblast|p2a: Florges -|-damage|p2a: Florges|22/360 -| -|-heal|p2a: Florges|44/360|[from] item: Leftovers -|turn|334 -|c|★Crime♥|ow ow ow -|c|★Crime♥|close -|c|★CHEF BOY4RDEEZNUTS|nooooooooooooooooooo -|choice|move 4|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Florges|224/360|[from] move: Wish|[wisher] Florges -|-heal|p2a: Florges|246/360|[from] item: Leftovers -|turn|335 -|c| tuxedo_cat|I could only imagine this taking place in the anime universe, in like the League... -|c| tuxedo_cat|And the crowd would have left by that point. -|choice|move 1|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Redbull|Moonblast|p2a: Florges -|-damage|p2a: Florges|128/360 -| -|-heal|p2a: Florges|150/360|[from] item: Leftovers -|turn|336 -|c| tuxedo_cat|Tournament over. -|c| lollity|ah -|c| tuxedo_cat|Sun is rising... -|choice|move 4|move 3 -| -|move|p2a: Florges|Aromatherapy|p2a: Florges -|-cureteam|p2a: Florges|[from] move: Aromatherapy -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Florges|330/360|[from] move: Wish|[wisher] Florges -|-heal|p2a: Florges|352/360|[from] item: Leftovers -|turn|337 -|c| tuxedo_cat|New trainers starting... -|choice|move 4|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Florges|360/360|[from] item: Leftovers -|turn|338 -|c| lollity|and ash's companions are just sleeping on a bnech -|c| tuxedo_cat|And by the time the next league comes around, it'll still be going. -|choice|move 1|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|197/386 -|-damage|p2a: Heatran|149/386|[from] Stealth Rock -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|85/386 -| -|-heal|p2a: Heatran|265/386|[from] move: Wish|[wisher] Florges -|-heal|p2a: Heatran|289/386|[from] item: Leftovers -|turn|339 -|c|★Crime♥|gosh -|c|★Crime♥|florges back to life -|c| lollity|and i bet -|c| tuxedo_cat|Battling with tents and campfires on each side. -|c| lollity|both of you have like 10 max revives -|c| lollity|in your pokcket -|c|★CHEF BOY4RDEEZNUTS|howd u know lol -|choice|switch 6|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-heal|p2a: Heatran|313/386|[from] item: Leftovers -|turn|340 -|c|★Crime♥|oke im gonna stay -|c|★Crime♥|dont earthquake me -|choice|move 1|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|160/334 -|-damage|p2a: Skarmory|119/334|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|341 -|c|★Crime♥|lol -|c| lollity|oshit -|c| lollity|rekt -|c|★CHEF BOY4RDEEZNUTS|skarm needs to die lol -|c| lollity|the ssweep boys -|c| tuxedo_cat|And so the cycle continues. -|c|★Crime♥|can you guys get more viewers -|c|★CHEF BOY4RDEEZNUTS|i cant flamethrower with tran around... -|c| General Zelgius|shouldn't someone run out of pp by now? -|choice|switch 4|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|286/334 -| -|turn|342 -|choice|move 2|switch 5 -| -|switch|p2a: Cobalion|Cobalion|326/386 -|-damage|p2a: Cobalion|314/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Cobalion -|-status|p2a: Cobalion|par -| -|turn|343 -|c| lollity|nah -|c| lollity|they have leppa berries -|c| lollity|just a backapck full of leppa berries -|c|★Crime♥|i need more support in my team -|c|★Crime♥|another pokemon with wish and heal bell -|c|★Crime♥|maybe a clefable -|c|★Crime♥|instead of cobalion -|c|★Crime♥|but cobalion is great -|c|★CHEF BOY4RDEEZNUTS|alomomola -|c|★CHEF BOY4RDEEZNUTS|that thing never dies -|c|★Crime♥|lol -|c|★Crime♥|no? :D -|c| tuxedo_cat|Not likely. If each move has say... 10 moves to it, that'd last for 240 turns. -|c|★Crime♥|might try it -|c| tuxedo_cat|And since most have 20+... -|choice|move 3|move 4 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|303/386 par -|choice|switch 4| -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|cant|p2a: Cobalion|par -| -|turn|344 -|c| General Zelgius|rip... -|choice|switch 5|switch 5 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Skarmory|Skarmory, F|286/334 -|-damage|p2a: Skarmory|245/334|[from] Stealth Rock -| -|turn|345 -|choice|move 1|switch 5 -| -|switch|p2a: Cobalion|Cobalion|303/386 par -|-damage|p2a: Cobalion|291/386 par|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Cobalion -|-damage|p2a: Cobalion|191/386 par -| -|turn|346 -|c| tuxedo_cat|Factor in paralysis and other stop-attack conditions... -|c| tuxedo_cat|Switches... -|choice|move 1|move 3 -| -|move|p1a: Fatty|Seismic Toss|p2a: Cobalion -|-damage|p2a: Cobalion|91/386 par -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|turn|347 -|c| tuxedo_cat|And yeah. The battle will last just about as long as the universe. -|c|★CHEF BOY4RDEEZNUTS|sleep^ -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|switch 2|switch 3 -| -|switch|p2a: Chansey|Chansey, F|402/642 -|-damage|p2a: Chansey|322/642|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|246/301 -| -|turn|348 -|choice|move 3|move 3 -| -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|642/642 -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|562/642 brn|[from] brn -|turn|349 -|choice|switch 4|switch 2 -| -|switch|p2a: Heatran|Heatran, F, shiny|313/386 -|-damage|p2a: Heatran|265/386|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-heal|p2a: Heatran|289/386|[from] item: Leftovers -|turn|350 -|choice|switch 3|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Taunt|p1a: U Jelly Bruh? -|-start|p1a: U Jelly Bruh?|move: Taunt -| -|-heal|p2a: Heatran|313/386|[from] item: Leftovers -|turn|351 -|c|★CHEF BOY4RDEEZNUTS|still got 56 of them rapid spins left :p -|c|★Crime♥|lol -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|295/394 -| -|turn|352 -|choice|move 2|switch 3 -| -|switch|p2a: Cobalion|Cobalion|386/386 slp -|-damage|p2a: Cobalion|374/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Cobalion -|-immune|p2a: Cobalion|[msg] -| -|-end|p1a: U Jelly Bruh?|move: Taunt -|turn|353 -|choice|switch 5|switch 6 -| -|switch|p2a: Florges|Florges, F|360/360 -|-damage|p2a: Florges|315/360|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-heal|p2a: Florges|337/360|[from] item: Leftovers -|turn|354 -|c|★Crime♥|its funny -|c|★Crime♥|you didnt knock off my florges or heatran -|c|★Crime♥|neither chansey -|c|★Crime♥|skarmory cobalion didnt matter -|c|★Crime♥|lol -|c|★CHEF BOY4RDEEZNUTS|ive been trying to the whole game -|c|★Crime♥|thats why i got them knocked off -|c|★Crime♥|xDDDDDDD -|choice|move 2|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|245/334 -|-damage|p2a: Skarmory|204/334|[from] Stealth Rock -|move|p1a: Annoying AF|Toxic|p2a: Skarmory|[miss] -|-miss|p1a: Annoying AF|p2a: Skarmory -| -|turn|355 -|choice|switch 4|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|246/301 -|move|p2a: Skarmory|Whirlwind|p1a: I <3 Stall -|move|p1a: I <3 Stall|Whirlwind|p2a: Skarmory|[from]Magic Bounce -|drag|p2a: Florges|Florges, F|337/360 -|-damage|p2a: Florges|292/360|[from] Stealth Rock -| -|-heal|p2a: Florges|314/360|[from] item: Leftovers -|turn|356 -|c|★Crime♥|weeeeeeeee -|choice|switch 3|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Florges|Protect|p2a: Florges -|-fail|p2a: Florges -| -|-heal|p2a: Florges|336/360|[from] item: Leftovers -|turn|357 -|choice|switch 5|switch 6 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Cobalion|Cobalion|374/386 slp -|-damage|p2a: Cobalion|362/386 slp|[from] Stealth Rock -| -|turn|358 -|c|★Crime♥|omg -|c|★Crime♥|im gonna break down my record -|c|★Crime♥|!! -|c|★Crime♥|411 turns -|c|★Crime♥|:P -|c|★CHEF BOY4RDEEZNUTS|411 really? -|c|★CHEF BOY4RDEEZNUTS|wow -|c|★Crime♥|yes -|choice|switch 4|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|turn|359 -|choice|move 2|move 1 -| -|move|p1a: Annoying AF|Toxic|p2a: Slowbro -|-status|p2a: Slowbro|tox -|move|p2a: Slowbro|Scald|p1a: Annoying AF -|-supereffective|p1a: Annoying AF -|-damage|p1a: Annoying AF|112/352 tox -| -|-heal|p1a: Annoying AF|156/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|360 -|c|★CHEF BOY4RDEEZNUTS|worth it -|choice|move 3|move 1 -| -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|68/352 tox -|move|p2a: Slowbro|Scald|p1a: Annoying AF -|-supereffective|p1a: Annoying AF -|-end|p1a: Annoying AF|Substitute -| -|-heal|p1a: Annoying AF|112/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|361 -|choice|move 4|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|204/334 -|-damage|p2a: Skarmory|163/334|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p1a: Annoying AF|156/352 tox|[from] ability: Poison Heal -|turn|362 -|choice|move 2|move 2 -| -|move|p1a: Annoying AF|Toxic|p2a: Skarmory|[miss] -|-miss|p1a: Annoying AF|p2a: Skarmory -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|330/334 -| -|-heal|p1a: Annoying AF|200/352 tox|[from] ability: Poison Heal -|turn|363 -|c|★CHEF BOY4RDEEZNUTS|time to heal up -|c|★Crime♥|lol -|c|★CHEF BOY4RDEEZNUTS|yummy poison -|c|★Crime♥|wanted to crit you -|choice|move 2|move 3 -| -|move|p1a: Annoying AF|Toxic|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -|move|p2a: Skarmory|Defog|p1a: Annoying AF -|-unboost|p1a: Annoying AF|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|-heal|p1a: Annoying AF|244/352 tox|[from] ability: Poison Heal -|turn|364 -|choice|move 4|move 4 -| -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-singleturn|p1a: Annoying AF|Protect -|move|p2a: Skarmory|Whirlwind|p1a: Annoying AF -|drag|p1a: Fatty|Chansey, F|642/642 -| -|turn|365 -|c| General Zelgius|4 more roosts on skarmory -|choice|move 1|switch 6 -| -|switch|p2a: Florges|Florges, F|336/360 -|move|p1a: Fatty|Seismic Toss|p2a: Florges -|-damage|p2a: Florges|236/360 -| -|-heal|p2a: Florges|258/360|[from] item: Leftovers -|turn|366 -|choice|move 2|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: Fatty|Toxic|p2a: Florges -|-activate|p2a: Florges|Protect -| -|-heal|p2a: Florges|280/360|[from] item: Leftovers -|turn|367 -|c|★Crime♥|but -|c|★Crime♥|we got the wishes -|c|★Crime♥|left -|choice|move 1|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Fatty|Seismic Toss|p2a: Florges -|-damage|p2a: Florges|180/360 -| -|-heal|p2a: Florges|202/360|[from] item: Leftovers -|turn|368 -|choice|move 3|move 1 -| -|move|p2a: Florges|Moonblast|p1a: Fatty -|-damage|p1a: Fatty|578/642 -|-unboost|p1a: Fatty|spa|1 -|move|p1a: Fatty|Wish|p1a: Fatty -| -|-heal|p2a: Florges|360/360|[from] move: Wish|[wisher] Florges -|turn|369 -|c| General Zelgius|true, that was the the lowest healing move pp I saw -|choice|move 2|move 1 -| -|move|p2a: Florges|Moonblast|p1a: Fatty -|-damage|p1a: Fatty|517/642 -|move|p1a: Fatty|Toxic|p2a: Florges -|-status|p2a: Florges|tox -| -|-heal|p1a: Fatty|642/642|[from] move: Wish|[wisher] Fatty -|-damage|p2a: Florges|338/360 tox|[from] psn -|turn|370 -|choice|move 1|move 3 -| -|move|p2a: Florges|Aromatherapy|p2a: Florges -|-cureteam|p2a: Florges|[from] move: Aromatherapy -|move|p1a: Fatty|Seismic Toss|p2a: Florges -|-damage|p2a: Florges|238/360 -| -|-heal|p2a: Florges|260/360|[from] item: Leftovers -|turn|371 -|c|★CHEF BOY4RDEEZNUTS|last aromatherapy left -|c|★Crime♥|:( -|c|★Crime♥|ill RAGE -|c|★Crime♥|QUIT -|c|★Crime♥|NOAW. -|c| General Zelgius|that would be so lame -|c|★CHEF BOY4RDEEZNUTS|agreed lol -|c|★Crime♥|lol -|choice|move 2|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|313/386 -|move|p1a: Fatty|Toxic|p2a: Heatran -|-immune|p2a: Heatran|[msg] -| -|-heal|p2a: Heatran|337/386|[from] item: Leftovers -|turn|372 -|c| tuxedo_cat|I walked off for a bit... -|choice|switch 3|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|246/301 -|move|p2a: Heatran|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Heatran|[from]Magic Bounce -|drag|p2a: Florges|Florges, F|260/360 -| -|-heal|p2a: Florges|282/360|[from] item: Leftovers -|turn|373 -|c| tuxedo_cat|I shouldn't be surprised that nothing has changed. -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|switch 3|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|337/386 -|switch|p1a: Fatty|Chansey, F|642/642 -| -|-heal|p2a: Heatran|361/386|[from] item: Leftovers -|turn|374 -|c| General Zelgius|yeah I played a game of league during this -|choice|move 1|move 4 -| -|move|p2a: Heatran|Taunt|p1a: Fatty -|-start|p1a: Fatty|move: Taunt -|move|p1a: Fatty|Seismic Toss|p2a: Heatran -|-damage|p2a: Heatran|261/386 -| -|-heal|p2a: Heatran|285/386|[from] item: Leftovers -|turn|375 -|c| tuxedo_cat|Is this like the countdown to the Force Awakens? -|c| lollity|i got my phd during this -|c| General Zelgius|lmao -|c|★Crime♥|omg -|c| tuxedo_cat|When this ends, the movie will come out? -|c|★Crime♥|400 turns almost -|choice|switch 4|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|turn|376 -|choice|move 4|move 2 -| -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-singleturn|p2a: Slowbro|Protect -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-activate|p2a: Slowbro|Protect -| -|turn|377 -|c|★CHEF BOY4RDEEZNUTS|55 moar rapid spins :p -|c|★Crime♥|rapid spin time? -|c| lollity|i witnessed my childrens' graduation -|choice|switch 4|switch 3 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Cobalion|Cobalion|362/386 -| -|turn|378 -|c| tuxedo_cat|OH GOD! -|choice|switch 2|move 1 -| -|switch|p1a: Annoying AF|Gliscor, M|244/352 tox -|move|p2a: Cobalion|Close Combat|p1a: Annoying AF -|-resisted|p1a: Annoying AF -|-damage|p1a: Annoying AF|202/352 tox -|-unboost|p2a: Cobalion|def|1 -|-unboost|p2a: Cobalion|spd|1 -| -|-heal|p1a: Annoying AF|246/352 tox|[from] ability: Poison Heal -|turn|379 -|c| tuxedo_cat|There are 64 rapid spins! -|c| lollity|OH GOD -|c| lollity|oh jesus -|c|★CHEF BOY4RDEEZNUTS|thought it was cc -|choice|switch 5|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|330/334 -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|380 -|c|★CHEF BOY4RDEEZNUTS|2 defogs left -|choice|move 4|switch 6 -| -|switch|p2a: Cobalion|Cobalion|362/386 -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Cobalion -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|turn|381 -|c|★CHEF BOY4RDEEZNUTS|11 stealth rox -|c|★CHEF BOY4RDEEZNUTS|XD -|choice|switch 5|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|246/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: I <3 Stall|Sableye-Mega, M|246/301 -| -|turn|382 -|c| tuxedo_cat|Am I the only one who thinks that moves should have a max of say... 30 PP? -|choice|move 3|switch 4 -| -|switch|p2a: Florges|Florges, F|282/360 -|-damage|p2a: Florges|237/360|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Florges -|-status|p2a: Florges|brn -| -|-heal|p2a: Florges|259/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|214/360 brn|[from] brn -|turn|383 -|choice|switch 4|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Florges|Wish|p2a: Florges -| -|-heal|p2a: Florges|236/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|191/360 brn|[from] brn -|turn|384 -|c|★Crime♥|lol -|c| General Zelgius|that would be nice -|choice|move 4|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Florges -|-activate|p2a: Florges|Protect -| -|-heal|p2a: Florges|360/360 brn|[from] move: Wish|[wisher] Florges -|-damage|p2a: Florges|315/360 brn|[from] brn -|turn|385 -|choice|move 3|switch 4 -| -|switch|p2a: Cobalion|Cobalion|362/386 -|-damage|p2a: Cobalion|350/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|339/386 -|-ability|p2a: Cobalion|Justified|boost -|-boost|p2a: Cobalion|atk|1 -| -|turn|386 -|c| General Zelgius|but having the same amount of sr as rapid spins would be really annoying -|choice|switch 3|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|246/352 tox -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|165/352 tox -| -|-heal|p1a: Annoying AF|209/352 tox|[from] ability: Poison Heal -|turn|387 -|choice|move 4|move 4 -| -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-singleturn|p1a: Annoying AF|Protect -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: I <3 Stall|Sableye-Mega, M|246/301 -| -|turn|388 -|c|★Crime♥|bye -|c|★Crime♥|XD -|c| tuxedo_cat|This is the battle of the century... Because it's lasted about a century. -|choice|move 4|switch 4 -| -|switch|p2a: Florges|Florges, F|315/360 brn -|-damage|p2a: Florges|270/360 brn|[from] Stealth Rock -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -| -|-heal|p2a: Florges|292/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|247/360 brn|[from] brn -|turn|389 -|c| General Zelgius|The hundred year war -|choice|switch 5|switch 4 -| -|switch|p2a: Cobalion|Cobalion|339/386 -|-damage|p2a: Cobalion|327/386|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|390 -|c| tuxedo_cat|Pfft! -|c| lollity|i just had grandkids -|c| lollity|jesus christ -|c|★CHEF BOY4RDEEZNUTS|the potato famine was shorter than this -|c| lollity|are you guys almost out of pp? -|c|★Crime♥|lmfao -|c|★CHEF BOY4RDEEZNUTS|nope lol -|choice|switch 5|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Cobalion|[from]Magic Bounce -|drag|p2a: Skarmory|Skarmory, F|330/334 -|-damage|p2a: Skarmory|289/334|[from] Stealth Rock -| -|turn|391 -|c|★Crime♥|we should make a stall team together CHEF boy -|c|★Crime♥|:_: -|c| lollity|how about -|c| lollity|6 mews -|c| lollity|recover moonlight -|c| lollity|and some other heals -|c|★Crime♥|1 bisharp and they are all gone -|c|★Crime♥|with knock off sword dance -|c|★CHEF BOY4RDEEZNUTS|6 FAT PINK MONS -|c|★Crime♥|XD -|choice|move 3|switch 6 -| -|switch|p2a: Cobalion|Cobalion|327/386 -|-damage|p2a: Cobalion|315/386|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Cobalion -|-status|p2a: Cobalion|brn -| -|-damage|p2a: Cobalion|267/386 brn|[from] brn -|turn|392 -|choice|switch 4|move 3 -| -|switch|p1a: Annoying AF|Gliscor, M|209/352 tox -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|-heal|p1a: Annoying AF|253/352 tox|[from] ability: Poison Heal -|turn|393 -|c|★CHEF BOY4RDEEZNUTS|kanye west used kanye rest -|c| tuxedo_cat|There should really be a draw option. -|choice|switch 3|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|289/334 -|-damage|p2a: Skarmory|248/334|[from] Stealth Rock -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|turn|394 -|choice|move 1|switch 6 -| -|switch|p2a: Cobalion|Cobalion|386/386 slp -|-damage|p2a: Cobalion|374/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Cobalion -|-damage|p2a: Cobalion|266/386 slp -| -|turn|395 -|choice|switch 3|move 3 -| -|switch|p1a: Annoying AF|Gliscor, M|253/352 tox -|cant|p2a: Cobalion|slp -| -|-heal|p1a: Annoying AF|297/352 tox|[from] ability: Poison Heal -|turn|396 -|choice|move 3|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|248/334 -|-damage|p2a: Skarmory|207/334|[from] Stealth Rock -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|209/352 tox -| -|-heal|p1a: Annoying AF|253/352 tox|[from] ability: Poison Heal -|turn|397 -|choice|switch 4|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|334/334 -| -|turn|398 -|choice|switch 5|switch 2 -| -|switch|p2a: Chansey|Chansey, F|562/642 -|-damage|p2a: Chansey|482/642|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|399 -|c|★Crime♥|omg -|c|★Crime♥|2 turns -|c|★Crime♥|1 -|c|★Crime♥|400+ -|c| lennylennylenny|better be good -|choice|move 2|switch 6 -| -|switch|p2a: Cobalion|Cobalion|266/386 slp -|-damage|p2a: Cobalion|254/386 slp|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Cobalion -|-fail|p2a: Cobalion -| -|turn|400 -|choice|switch 4|move 3 -| -|switch|p1a: Annoying AF|Gliscor, M|253/352 tox -|cant|p2a: Cobalion|slp -| -|-heal|p1a: Annoying AF|297/352 tox|[from] ability: Poison Heal -|turn|401 -|c| General Zelgius|400 hype -|c|★CHEF BOY4RDEEZNUTS|oh snap -|choice|switch 6|move 3 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|turn|402 -|c| lollity|wait how many are we at? -|c|★Crime♥|lol -|choice|move 4|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|285/386 -|-damage|p2a: Heatran|237/386|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|261/386|[from] item: Leftovers -|turn|403 -|choice|move 1|move 3 -| -|move|p2a: Heatran|Stealth Rock|p1a: Redbull -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|229/386 -| -|-heal|p2a: Heatran|253/386|[from] item: Leftovers -|turn|404 -|c| lennylennylenny|hey alia that sounds muslim to me -|c| lollity|i dont see the correct turn number -|c| lollity|which turn is it? -|c| lennylennylenny|4040 -|choice|move 1|move 2 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|223/386 -|move|p2a: Heatran|Roar|p1a: Redbull -|drag|p1a: Fatty|Chansey, F|642/642 -|-damage|p1a: Fatty|562/642|[from] Stealth Rock -| -|-heal|p2a: Heatran|247/386|[from] item: Leftovers -|turn|405 -|c| lennylennylenny|404* -|c| lollity|jeeeeez -|choice|switch 3|switch 4 -| -|switch|p2a: Florges|Florges, F|247/360 brn -|-damage|p2a: Florges|202/360 brn|[from] Stealth Rock -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|340/363|[from] item: Black Sludge -|-heal|p2a: Florges|224/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|179/360 brn|[from] brn -|turn|406 -|c|★Crime♥|dont knock off me -|choice|move 4|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|337/394 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|362/363|[from] item: Black Sludge -|turn|407 -|c|★CHEF BOY4RDEEZNUTS|53 moar rapid spins -|choice|move 2|switch 5 -| -|switch|p2a: Cobalion|Cobalion|386/386 slp -|-damage|p2a: Cobalion|374/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Cobalion -|-immune|p2a: Cobalion|[msg] -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|turn|408 -|c| lennylennylenny|404 no one died yet -|c| lennylennylenny|how -|c|★CHEF BOY4RDEEZNUTS|stall for daysssss -|choice|switch 6|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|297/352 tox -|cant|p2a: Cobalion|slp -| -|-heal|p1a: Annoying AF|341/352 tox|[from] ability: Poison Heal -|turn|409 -|c|★Crime♥|2 scals -|c|★Crime♥|scalds -|choice|switch 3|move 4 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|cant|p2a: Cobalion|slp -| -|turn|410 -|choice|switch 3|move 1 -| -|switch|p1a: Annoying AF|Gliscor, M|341/352 tox -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Close Combat|p1a: Annoying AF -|-resisted|p1a: Annoying AF -|-damage|p1a: Annoying AF|303/352 tox -|-unboost|p2a: Cobalion|def|1 -|-unboost|p2a: Cobalion|spd|1 -| -|-heal|p1a: Annoying AF|347/352 tox|[from] ability: Poison Heal -|turn|411 -|c| General Zelgius|we made it -|choice|switch 4|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|334/334 -|-damage|p2a: Skarmory|293/334|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|412 -|c|★Crime♥|omg -|c|★Crime♥|new record -|c| General Zelgius|record broken -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|move 4|switch 2 -| -|switch|p2a: Cobalion|Cobalion|374/386 -|-damage|p2a: Cobalion|362/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Cobalion -|-fail|p2a: Cobalion -| -|turn|413 -|c|★Crime♥|can we hit 500? -|choice|switch 4|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|347/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|turn|414 -|c|★CHEF BOY4RDEEZNUTS|probs lol -|choice|move 1|move 2 -| -|move|p2a: Cobalion|Iron Head|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|299/363 -|move|p1a: U Jelly Bruh?|Scald|p2a: Cobalion -|-damage|p2a: Cobalion|254/386 -| -|-heal|p1a: U Jelly Bruh?|321/363|[from] item: Black Sludge -|turn|415 -|choice|switch 6|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|347/352 tox -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|296/352 tox -| -|-heal|p1a: Annoying AF|340/352 tox|[from] ability: Poison Heal -|turn|416 -|c|★Crime♥|1 scald babe -|c|★Crime♥|:3 -|choice|move 1|move 3 -| -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -|move|p1a: Annoying AF|Earthquake|p2a: Cobalion -|-supereffective|p2a: Cobalion -|-crit|p2a: Cobalion -|-damage|p2a: Cobalion|180/386 slp -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|417 -|c|★CHEF BOY4RDEEZNUTS|PHAT -|c|★CHEF BOY4RDEEZNUTS|jesus -|choice|switch 5|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|293/334 -|-damage|p2a: Skarmory|252/334|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|turn|418 -|c|★Crime♥|not much dmg at all -|c|★Crime♥|with a crit.. -|choice|move 1|switch 6 -| -|switch|p2a: Chansey|Chansey, F|482/642 -|-damage|p2a: Chansey|402/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|419 -|c|★CHEF BOY4RDEEZNUTS|THAT WAS A CRIT? HOLY SHIT -|c| General Zelgius|nothing here can do much damage -|c| General Zelgius|53% is good -|c|★CHEF BOY4RDEEZNUTS|trueeee -|choice|move 3|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Slowbro|[miss] -|-miss|p1a: I <3 Stall|p2a: Slowbro -| -|turn|420 -|choice|move 1|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|247/386 -|-damage|p2a: Heatran|199/386|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Heatran -|-damage|p2a: Heatran|130/386 -|-unboost|p2a: Heatran|spd|1 -| -|-heal|p2a: Heatran|154/386|[from] item: Leftovers -|turn|421 -|c| lollity|a dude on the internet said his record was 1k + -|c| lollity|can we get there? -|choice|move 1|switch 5 -| -|switch|p2a: Chansey|Chansey, F|402/642 -|-damage|p2a: Chansey|322/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|422 -|c| General Zelgius|don't think so -|c|★Crime♥|with alot of switching yes -|c|★Crime♥|but that isnt legit -|c|★Crime♥|this battle is legit -|c| General Zelgius|^ -|c| lollity|i dont think he used switching -|choice|switch 5|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Chansey|Wish|p2a: Chansey -| -|turn|423 -|c| lollity|it was just a really stally team -|c|★CHEF BOY4RDEEZNUTS|everything with rest lol -|c| tuxedo_cat|One side would run out of PP, if it were a legitimate battle. -|c| Bambi22|what turn now? -|c|★CHEF BOY4RDEEZNUTS|423 -|choice|switch 2|switch 2 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|switch|p2a: Cobalion|Cobalion|180/386 slp -|-damage|p2a: Cobalion|168/386 slp|[from] Stealth Rock -| -|-heal|p2a: Cobalion|386/386 slp|[from] move: Wish|[wisher] Chansey -|turn|424 -|c| Bambi22|it stopped showing the turn number on mine -|choice|move 2|switch 3 -| -|switch|p2a: Florges|Florges, F|179/360 brn -|-damage|p2a: Florges|134/360 brn|[from] Stealth Rock -|move|p1a: Redbull|Flamethrower|p2a: Florges -|-damage|p2a: Florges|94/360 brn -| -|-heal|p2a: Florges|116/360 brn|[from] item: Leftovers -|-damage|p2a: Florges|71/360 brn|[from] brn -|turn|425 -|choice|move 1|move 3 -| -|move|p2a: Florges|Aromatherapy|p2a: Florges -|-cureteam|p2a: Florges|[from] move: Aromatherapy -|move|p1a: Redbull|Moonblast|p2a: Florges -|-damage|p2a: Florges|14/360 -| -|-heal|p2a: Florges|36/360|[from] item: Leftovers -|turn|426 -|c|★CHEF BOY4RDEEZNUTS|nooooooooooooooo -|c|★Crime♥|lol -|c| tuxedo_cat|YOU CAN DO IT! -|choice|move 2|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: Redbull|Flamethrower|p2a: Florges -|-activate|p2a: Florges|Protect -| -|-heal|p2a: Florges|58/360|[from] item: Leftovers -|turn|427 -|c|★Crime♥|here we go again -|c| tuxedo_cat|NO! -|c|★Crime♥|XD -|choice|move 1|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Redbull|Moonblast|p2a: Florges -|-damage|p2a: Florges|1/360 -| -|-heal|p2a: Florges|23/360|[from] item: Leftovers -|turn|428 -|c|★Crime♥|lOL -|c|★Crime♥|LLOl -|c|★Crime♥|LOl -|c| General Zelgius|omg -|c|★Crime♥|LOL -|c|★Crime♥|LOl -|c| Bambi22|if only someone had spikes -|c|★Crime♥|LOL -|c|★Crime♥|LOL -|c| General Zelgius|fuck that -|c|★Crime♥|LOL -|c|★CHEF BOY4RDEEZNUTS|NOOOOOOOOOOOOOOOOOOOOOOOOOOO -|c| tuxedo_cat|Calm mind! -|c|★Crime♥|LOL -|c|★Crime♥|LOL -|c|★Crime♥|LOL -|c|★Crime♥|LOL -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|move 4|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Florges|203/360|[from] move: Wish|[wisher] Florges -|-heal|p2a: Florges|225/360|[from] item: Leftovers -|turn|429 -|choice|move 4|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Florges|247/360|[from] item: Leftovers -|turn|430 -|c| lollity|what turn is it now -|c|★Crime♥|power of florges -|c|★Crime♥|XD -|choice|move 4|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|154/386 -|-damage|p2a: Heatran|106/386|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|286/386|[from] move: Wish|[wisher] Florges -|-heal|p2a: Heatran|310/386|[from] item: Leftovers -|turn|431 -|c|★Crime♥|432 -|choice|switch 5|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Heatran|[from]Magic Bounce -|drag|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -| -|turn|432 -|choice|switch 3|switch 2 -| -|switch|p2a: Chansey|Chansey, F|322/642 -|-damage|p2a: Chansey|242/642|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|562/642 -| -|turn|433 -|choice|move 2|move 3 -| -|move|p1a: Fatty|Toxic|p2a: Chansey -|-status|p2a: Chansey|tox -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|563/642 tox -| -|-damage|p2a: Chansey|523/642 tox|[from] psn -|turn|434 -|choice|move 1|switch 3 -| -|switch|p2a: Cobalion|Cobalion|386/386 -|-damage|p2a: Cobalion|374/386|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Cobalion -|-damage|p2a: Cobalion|274/386 -| -|turn|435 -|choice|switch 2|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: Fatty|Chansey, F|562/642 -| -|turn|436 -|c| tuxedo_cat|...I take it back. -|choice|switch 2|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|292/352 tox -| -|-heal|p1a: Annoying AF|336/352 tox|[from] ability: Poison Heal -|turn|437 -|c| tuxedo_cat|You COULD go for 1k moves. -|c| lollity|are you guys out of pp yet? -|c|★Crime♥|not yet -|c|★CHEF BOY4RDEEZNUTS|nope -|choice|switch 4|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|252/334 -|-damage|p2a: Skarmory|211/334|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|438 -|c| lollity|whos gonna win this game -|c|★Crime♥|think we get to turn 500 -|c| lollity|is my guestion -|c| tuxedo_cat|You can check, lollity. -|c| lollity|ah so you can -|choice|move 4|switch 6 -| -|switch|p2a: Cobalion|Cobalion|274/386 -|-damage|p2a: Cobalion|262/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Cobalion -|-fail|p2a: Cobalion -| -|turn|439 -|choice|switch 4|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|336/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: U Jelly Bruh?|Tentacruel, M|321/363 -| -|-heal|p1a: U Jelly Bruh?|343/363|[from] item: Black Sludge -|turn|440 -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-crit|p2a: Cobalion -|-damage|p2a: Cobalion|257/386 -|move|p2a: Cobalion|Roar|p1a: U Jelly Bruh? -|drag|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|turn|441 -|c|★CHEF BOY4RDEEZNUTS|52 more rapid spinzzzz -|choice|move 1|switch 3 -| -|switch|p2a: Chansey|Chansey, F|523/642 -|-damage|p2a: Chansey|443/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|442 -|choice|switch 5|move 2 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|move|p2a: Chansey|Toxic|p1a: Redbull -|-status|p1a: Redbull|tox -| -|-damage|p1a: Redbull|369/393 tox|[from] psn -|turn|443 -|choice|move 3|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|310/386 -|-damage|p2a: Heatran|262/386|[from] Stealth Rock -|move|p1a: Redbull|Wish|p1a: Redbull -| -|-heal|p2a: Heatran|286/386|[from] item: Leftovers -|-heal|p1a: Redbull|393/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|345/393 tox|[from] psn -|turn|444 -|c| Bambi22|wait ur unaware? -|c|★CHEF BOY4RDEEZNUTS|yup -|choice|switch 2|move 3 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|move|p2a: Heatran|Stealth Rock|p1a: Fatty -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p1a: Fatty|642/642|[from] move: Wish|[wisher] Redbull -|-heal|p2a: Heatran|310/386|[from] item: Leftovers -|turn|445 -|c|★CHEF BOY4RDEEZNUTS|took this long for it to be revealed lol -|c| Bambi22|unless I didn't notice u taking rocks damage -|c|★Crime♥|ye -|c|★Crime♥|lol -|c|★CHEF BOY4RDEEZNUTS|i spun them away before bringing clef in -|c| tuxedo_cat|So 440 moves in, we find out there's another 16 to add to the counter. -|choice|move 4|move 1 -| -|move|p2a: Heatran|Lava Plume|p1a: Fatty -|-damage|p1a: Fatty|578/642 -|move|p1a: Fatty|Heal Bell|p1a: Fatty -|-cureteam|p1a: Fatty|[from] move: HealBell -| -|-heal|p2a: Heatran|334/386|[from] item: Leftovers -|turn|446 -|choice|switch 3|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|343/363 -|-damage|p1a: U Jelly Bruh?|298/363|[from] Stealth Rock -|move|p2a: Heatran|Taunt|p1a: U Jelly Bruh? -|-start|p1a: U Jelly Bruh?|move: Taunt -| -|-heal|p1a: U Jelly Bruh?|320/363|[from] item: Black Sludge -|-heal|p2a: Heatran|358/386|[from] item: Leftovers -|turn|447 -|choice|move 3|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|301/394 -| -|-heal|p1a: U Jelly Bruh?|342/363|[from] item: Black Sludge -|turn|448 -|choice|move 4|move 1 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|293/394 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -|move|p2a: Slowbro|Scald|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|312/363 -| -|-heal|p1a: U Jelly Bruh?|334/363|[from] item: Black Sludge -|-end|p1a: U Jelly Bruh?|move: Taunt -|turn|449 -|choice|switch 3|switch 3 -| -|switch|p1a: Fatty|Chansey, F|578/642 -|switch|p2a: Cobalion|Cobalion|257/386 -|-damage|p2a: Cobalion|245/386|[from] Stealth Rock -| -|turn|450 -|choice|switch 6|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|336/352 -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: U Jelly Bruh?|Tentacruel, M|334/363 -| -|-heal|p1a: U Jelly Bruh?|356/363|[from] item: Black Sludge -|turn|451 -|choice|switch 3|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|336/352 -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|284/352 -| -|-status|p1a: Annoying AF|tox|[from] item: Toxic Orb -|turn|452 -|choice|move 1|switch 6 -| -|switch|p2a: Skarmory|Skarmory, F|211/334 -|-damage|p2a: Skarmory|170/334|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|-heal|p1a: Annoying AF|328/352 tox|[from] ability: Poison Heal -|turn|453 -|choice|switch 4|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|334/334 -| -|turn|454 -|choice|move 2|switch 4 -| -|switch|p2a: Chansey|Chansey, F|443/642 -|-damage|p2a: Chansey|363/642|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Chansey -|-status|p2a: Chansey|par -| -|turn|455 -|choice|move 1|move 3 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Chansey -|-damage|p2a: Chansey|209/642 par -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|530/642 par -| -|turn|456 -|c|★Crime♥|phew -|choice|move 3|switch 6 -| -|switch|p2a: Cobalion|Cobalion|245/386 -|-damage|p2a: Cobalion|233/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|223/386 -|choice|switch 4| -| -|switch|p1a: Annoying AF|Gliscor, M|328/352 tox -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|457 -|choice|move 2|move 3 -| -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -|move|p1a: Annoying AF|Toxic|p2a: Cobalion -|-fail|p2a: Cobalion -| -|turn|458 -|choice|switch 4|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|cant|p2a: Cobalion|slp -| -|turn|459 -|choice|move 4|move 4 -| -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Cobalion -|-fail|p2a: Cobalion -|cant|p2a: Cobalion|slp -| -|turn|460 -|choice|switch 4|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|461 -|choice|switch 5|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Cobalion|[from]Magic Bounce -|drag|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -| -|turn|462 -|c|★Crime♥|lmfao -|choice|move 3|switch 6 -| -|switch|p2a: Chansey|Chansey, F|530/642 -|-damage|p2a: Chansey|450/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|370/642 brn|[from] brn -|turn|463 -|c| lollity|you guys are still at half pp -|c| tuxedo_cat|Just calm mind to death. -|choice|switch 2|switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 -|-damage|p2a: Slowbro|345/394|[from] Stealth Rock -|switch|p1a: Redbull|Clefable, M|345/393 -| -|-heal|p1a: Redbull|369/393|[from] item: Leftovers -|turn|464 -|choice|switch 2|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Slowbro|Toxic|p1a: I <3 Stall -|move|p1a: I <3 Stall|Toxic|p2a: Slowbro|[from]Magic Bounce -|-status|p2a: Slowbro|tox -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|465 -|c| tuxedo_cat|Eventually, the chancey will run out of moves. -|c|★CHEF BOY4RDEEZNUTS|YUSSSSS -|choice|switch 6|switch 5 -| -|switch|p2a: Florges|Florges, F|247/360 -|-damage|p2a: Florges|202/360|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|578/642 -| -|-heal|p2a: Florges|224/360|[from] item: Leftovers -|turn|466 -|choice|move 2|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Fatty|Toxic|p2a: Florges|[miss] -|-miss|p1a: Fatty|p2a: Florges -| -|-heal|p2a: Florges|246/360|[from] item: Leftovers -|turn|467 -|c| lollity|can you pass turns in this game -|c|★CHEF BOY4RDEEZNUTS|noooooo -|choice|move 2|switch 6 -| -|switch|p2a: Chansey|Chansey, F|370/642 -|-damage|p2a: Chansey|290/642|[from] Stealth Rock -|move|p1a: Fatty|Toxic|p2a: Chansey -|-status|p2a: Chansey|tox -| -|-heal|p2a: Chansey|470/642 tox|[from] move: Wish|[wisher] Florges -|-damage|p2a: Chansey|430/642 tox|[from] psn -|turn|468 -|c| lollity|or is it like chess -|c| General Zelgius|you need to move -|choice|switch 3|switch 6 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|356/363 -|switch|p2a: Florges|Florges, F|246/360 -|-damage|p2a: Florges|201/360|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|-heal|p2a: Florges|223/360|[from] item: Leftovers -|turn|469 -|c| General Zelgius|so like chess -|c| tuxedo_cat|You can switch. That's sort of like a pass. -|choice|move 3|move 4 -| -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Florges -|-resisted|p2a: Florges -|-damage|p2a: Florges|190/360 -|-enditem|p2a: Florges|Leftovers|[from] move: Knock Off|[of] p1a: U Jelly Bruh? -|move|p2a: Florges|Wish|p2a: Florges -| -|turn|470 -|c|★CHEF BOY4RDEEZNUTS|NO MOAR LEFTIES -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|switch 3|move 1 -| -|switch|p1a: Fatty|Chansey, F|578/642 -|move|p2a: Florges|Moonblast|p1a: Fatty -|-damage|p1a: Fatty|515/642 -| -|-heal|p2a: Florges|360/360|[from] move: Wish|[wisher] Florges -|turn|471 -|choice|move 1|switch 3 -| -|switch|p2a: Cobalion|Cobalion|386/386 -|-damage|p2a: Cobalion|374/386|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Cobalion -|-damage|p2a: Cobalion|274/386 -| -|turn|472 -|c| General Zelgius|switching is not an offensive move but it can drastically change the state of the game -|c| Nass-T|niggas -|c| tuxedo_cat|Oh God... We're now 28 turns away from 500... -|choice|switch 6|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Cobalion|[from]Magic Bounce -|drag|p2a: Florges|Florges, F|360/360 -|-damage|p2a: Florges|315/360|[from] Stealth Rock -| -|turn|473 -|c| General Zelgius|wouldn't say it's a pass -|choice|switch 5|switch 6 -| -|switch|p2a: Chansey|Chansey, F|430/642 -|-damage|p2a: Chansey|350/642|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|474 -|c| tuxedo_cat|Switching is also the dumbest concept in the entire metagame. -|c| Nass-T|This is straight cancer -|c|★Crime♥|lmao -|choice|move 4|switch 3 -| -|switch|p2a: Cobalion|Cobalion|274/386 -|-damage|p2a: Cobalion|262/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Cobalion -|-fail|p2a: Cobalion -| -|turn|475 -|c| General Zelgius|been here since turn 143 -|c| tuxedo_cat|If you declared t-bolt, and your opponent swapped to an escadrill... -|c| Nass-T|You're just switching over and over lol -|choice|switch 4|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: Redbull|Clefable, M|369/393 -| -|-heal|p1a: Redbull|393/393|[from] item: Leftovers -|turn|476 -|c| Nass-T|I'm not impressed -|c| tuxedo_cat|WHY would you continue with t-bolt? -|c| tuxedo_cat|Why wouldn't you switch at the same time? -|choice|switch 5|switch 2 -| -|switch|p2a: Heatran|Heatran, F, shiny|358/386 -|-damage|p2a: Heatran|310/386|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|-heal|p2a: Heatran|334/386|[from] item: Leftovers -|turn|477 -|c| tuxedo_cat|Or pick another move... -|c|★Crime♥|this is stall -|c|★Crime♥|we have different play style's -|choice|move 2|switch 3 -| -|switch|p2a: Chansey|Chansey, F|350/642 -|-damage|p2a: Chansey|270/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|478 -|c| tuxedo_cat|Stalling isn't battling. -|c| Nass-T|Setup -|c|★Crime♥|stalling isnt easy... -|c|★Crime♥|1 mistake and you lost the game -|c| tuxedo_cat|The fact that no one's died in this battle yet is proof of that. -|c|★Crime♥|people underestimate it -|c| Amber Torrey|Different pokemon doesn't mean different playstyle -|c|★Crime♥|also -|c| tuxedo_cat|You guys are both using pure stall teams. -|c| lollity|have you guys considered using a leppa harvest pokemon -|c|★Crime♥|with stalling you cant get high in rankings.. -|c| lollity|so you never run out of pp -|c| tuxedo_cat|There's a difference. -|c| tuxedo_cat|Sort of. -|choice|switch 4|move 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|591/642 -| -|turn|479 -|choice|move 3|switch 2 -| -|switch|p2a: Cobalion|Cobalion|262/386 -|-damage|p2a: Cobalion|250/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|240/386 -|c| tuxedo_cat|And if stalling can't get you high, then why do so many people use it? -|choice|switch 2| -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|turn|480 -|c| lollity|it's fun for some people i guess -|c|★Crime♥|because tanking is fun -|c|★CHEF BOY4RDEEZNUTS|i dont really care about ratings -|c| tuxedo_cat|Oh yeah... Because everyone high up is a legendary whore. -|c| lollity|personally i dont like it -|c|★CHEF BOY4RDEEZNUTS|and yeah legendary whores are no fun -|choice|move 2|move 3 -| -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -|move|p1a: Annoying AF|Toxic|p2a: Cobalion -|-fail|p2a: Cobalion -| -|turn|481 -|c| tuxedo_cat|"I got a high score with kyurem-black, heatran, landorus, thunderous, tornadus, and keldo." -|c| Amber Torrey|only kind of stall i dislike is toxic protect stalling -|c| lollity|whats a legendary whore -|c| General Zelgius|for lower elos people will instantly quit when they one into one -|c| Amber Torrey|that is just a cop out -|c| tuxedo_cat|Indeed. -|choice|switch 2|move 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|cant|p2a: Cobalion|slp -| -|turn|482 -|c| tuxedo_cat|Here's my proposal. -|c| tuxedo_cat|Ban protect. -|c|★CHEF BOY4RDEEZNUTS|only iif i had taunt -|choice|switch 4|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|cant|p2a: Cobalion|slp -| -|turn|483 -|c| lollity|then everyone switches to detect :P -|c| tuxedo_cat|And make toxic a poison type exclusive move. -|c| Amber Torrey|Just shouldn't allow protect and toxic on the same pokemon -|choice|move 3|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|334/386 -|-damage|p2a: Heatran|286/386|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Heatran -|-start|p2a: Heatran|ability: Flash Fire -| -|-heal|p2a: Heatran|310/386|[from] item: Leftovers -|turn|484 -|c| tuxedo_cat|Nah. No protect, period. -|c| tuxedo_cat|It's a cop out move. -|c| Amber Torrey|how so? -|choice|switch 2|move 1 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Heatran|Lava Plume|p1a: Annoying AF -|-damage|p1a: Annoying AF|144/352 tox -| -|-heal|p2a: Heatran|334/386|[from] item: Leftovers -|-heal|p1a: Annoying AF|188/352 tox|[from] ability: Poison Heal -|turn|485 -|c| tuxedo_cat|It's the equivelent of saying "FORCEFIELD" in a playground battle. -|c| Amber Torrey|it blocks outrage users easy to get confused -|choice|move 4|switch 4 -| -|-end|p2a: Heatran|ability: Flash Fire|[silent] -|switch|p2a: Skarmory|Skarmory, F|334/334 -|-damage|p2a: Skarmory|293/334|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p1a: Annoying AF|232/352 tox|[from] ability: Poison Heal -|turn|486 -|c| tuxedo_cat|Yeah. And it's bullshit. What is a protect? -|c| lollity|yeahh but youre giving up the utility of a move slot -|c|★CHEF BOY4RDEEZNUTS|protect against mega lop high jump kick :p -|c| Amber Torrey|and it makes it so you can see what your opponent is gonna do -|c| tuxedo_cat|Why can a bellsprout use it to the same effectiveness as Arceus? -|c|★CHEF BOY4RDEEZNUTS|useful if you ask me -|c|★Crime♥|bellsprout stall -|choice|switch 4|move 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Skarmory|Whirlwind|p1a: TheMoreYouKnow -|drag|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|turn|487 -|c|★Crime♥|lma -|c|★Crime♥|oo -|c| tuxedo_cat|It has it's uses, yes. -|c|★Crime♥|!data bellsprout -|c|~|/data-pokemon Bellsprout - -|c|★CHEF BOY4RDEEZNUTS|lol -|c|★Crime♥|!data gluttony -|c|~|/data-ability Gluttony - -|choice|move 2|switch 2 -| -|switch|p2a: Chansey|Chansey, F|591/642 -|-damage|p2a: Chansey|511/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|488 -|c| tuxedo_cat|Bellsprout = Arceus in the use of protect. -|c| Amber Torrey|My most hated pokemon is in fact gliscor -|choice|switch 6|move 1 -| -|switch|p1a: Fatty|Chansey, F|515/642 -|move|p2a: Chansey|Seismic Toss|p1a: Fatty -|-damage|p1a: Fatty|415/642 -| -|turn|489 -|c| Amber Torrey|the master of toxic protect stalling -|c|★Crime♥|omg -|c|★Crime♥|i wanna smoke -|c|★CHEF BOY4RDEEZNUTS|i like stall for the sole purpose of making ppl salty -|c| tuxedo_cat|I'm from the days before fairies... -|c|★Crime♥|im in here for over 2 hours -|c| tuxedo_cat|Back in my day, dragons ruled the roost, and gliscors ruled the night. -|c| Amber Torrey|sigh why does everyone say fairies ruined the game? -|c| tuxedo_cat|And I was the vampire hunter. -|choice|move 3|switch 3 -| -|switch|p2a: Cobalion|Cobalion|386/386 slp -|-damage|p2a: Cobalion|374/386 slp|[from] Stealth Rock -|move|p1a: Fatty|Wish|p1a: Fatty -| -|turn|490 -|c| Amber Torrey|i'm so sorry your bs dragon types have a real counter now -|c| tuxedo_cat|PorygonZ with an ice beam and nasty plot. -|choice|switch 4|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|232/352 tox -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: Redbull|Clefable, M|393/393 -| -|turn|491 -|c| tuxedo_cat|I'm not complaining about fairies. -|choice|move 1|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|334/386 -|-damage|p2a: Heatran|286/386|[from] Stealth Rock -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|265/386 -| -|-heal|p2a: Heatran|289/386|[from] item: Leftovers -|turn|492 -|choice|move 3|move 3 -| -|move|p2a: Heatran|Stealth Rock|p1a: Redbull -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -|move|p1a: Redbull|Wish|p1a: Redbull -| -|-heal|p2a: Heatran|313/386|[from] item: Leftovers -|turn|493 -|choice|move 1|move 2 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|293/386 -|move|p2a: Heatran|Roar|p1a: Redbull -|drag|p1a: Fatty|Chansey, F|415/642 -|-damage|p1a: Fatty|335/642|[from] Stealth Rock -| -|-heal|p1a: Fatty|531/642|[from] move: Wish|[wisher] Redbull -|-heal|p2a: Heatran|317/386|[from] item: Leftovers -|turn|494 -|c| tuxedo_cat|I was just saying that I remember when toxic-gliscor was on EVERY team. -|c| Amber Torrey|still is -|c| lollity|hmm -|c| tuxedo_cat|Then aegislash showed up and they went away for a while. -|c| lollity|21 more stealth rocks -|c| tuxedo_cat|Then aegislash got banned... -|choice|switch 3|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -|move|p2a: Heatran|Taunt|p1a: U Jelly Bruh? -|-start|p1a: U Jelly Bruh?|move: Taunt -| -|-heal|p1a: U Jelly Bruh?|340/363|[from] item: Black Sludge -|-heal|p2a: Heatran|341/386|[from] item: Leftovers -|turn|495 -|c| tuxedo_cat|And they returned. -|c|★CHEF BOY4RDEEZNUTS|51 moar rapid spins lol -|choice|move 4|switch 6 -| -|switch|p2a: Florges|Florges, F|315/360 -|-damage|p2a: Florges|270/360|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Florges -|-damage|p2a: Florges|256/360 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|362/363|[from] item: Black Sludge -|turn|496 -|c| Amber Torrey|no earthpower on heatran? -|choice|switch 2|move 1 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Florges|Moonblast|p1a: TheMoreYouKnow -|-resisted|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|346/403 -| -|-heal|p1a: TheMoreYouKnow|371/403|[from] item: Leftovers -|turn|497 -|c| lollity|wait -|c| tuxedo_cat|I'm convinced that Smogon is ran by the dumbest competitive fans in the business. -|c| lollity|how does florges walk? -|c| lollity|it has no legs -|c|★Crime♥|lol -|c| Amber Torrey|it doesn;t -|c| Amber Torrey|florges floats -|c|★Crime♥|3 turns guys -|c|★Crime♥|omg -|c|★Crime♥|legit! -|c| lollity|how does it float -|choice|move 3|switch 4 -| -|switch|p2a: Cobalion|Cobalion|374/386 -|-damage|p2a: Cobalion|362/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|351/386 -|c| lollity|phsyics???? -|c|★CHEF BOY4RDEEZNUTS|holy shit lol -|c| Amber Torrey|by being a fairy -|choice|switch 5| -| -|switch|p1a: Annoying AF|Gliscor, M|232/352 tox -| -|-heal|p1a: Annoying AF|276/352 tox|[from] ability: Poison Heal -|turn|498 -|c| tuxedo_cat|They'll ban a Pokemon because they deem it "too powerful"... -|c|★Crime♥|will we hit 600+? -|c|★CHEF BOY4RDEEZNUTS|fuck logic thats why -|c| tuxedo_cat|When they could just as easily ban a particular moveset. -|choice|switch 6|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Cobalion|[from]Magic Bounce -|drag|p2a: Chansey|Chansey, F|511/642 -|-damage|p2a: Chansey|431/642|[from] Stealth Rock -| -|turn|499 -|c| Amber Torrey|to be fair Ageislash is extremely op -|choice|switch 4|move 1 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|move|p2a: Chansey|Seismic Toss|p1a: Redbull -|-damage|p1a: Redbull|293/393 -| -|-heal|p1a: Redbull|317/393|[from] item: Leftovers -|turn|500 -|c|+Jack Dalton|complex bans aren't intuitive -|c| tuxedo_cat|They'll treat the symptoms, but not the disease. -|c|★CHEF BOY4RDEEZNUTS|#FREEAEGI -|c|★Crime♥|500 -|c|★Crime♥|sweet jezus -|c| Amber Torrey|sword dance plus shadow sneak with insane attack stat -|c| Amber Torrey|and sacred sword for normal type counters -|c|+Jack Dalton|and it's easier to explain to people "hey this is too strong" than to go into all the intricacies about why a particular part of that thing is too strong -|c| tuxedo_cat|You people are weak. -|c| tuxedo_cat|Aegislash was fun to fight. -|c| tuxedo_cat|He had a dance to him. -|c| Amber Torrey|how so? -|choice|move 4|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|341/386 -|-damage|p2a: Heatran|293/386|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|317/386|[from] item: Leftovers -|-heal|p1a: Redbull|341/393|[from] item: Leftovers -|turn|501 -|c|+Jack Dalton|also some things are too strong because everything about them is too strong as a whole -|c| lennylennylenny|aegi was fun -|c| tuxedo_cat|And if you could dance in turn, he'd be taken down easily. -|c| Amber Torrey|every ageislash was the exact same thing -|c|★Crime♥|20 sec -|c| Amber Torrey|sword dance while staying defense form to never die -|c| Amber Torrey|shadow sneak sacred sword -|c| Amber Torrey|and protect -|c|+Jack Dalton|aegislash made a lot of things unviable because it was staple on every team -|c|★CHEF BOY4RDEEZNUTS|i think crime went on a smoke break lolk -|c| Amber Torrey|that was literally every ageislash -|c| General Zelgius|actually aegi got banned because he several very strong movesets -|c|★Crime♥|im back -|c|★Crime♥|:P -|choice|move 4|move 3 -| -|move|p2a: Heatran|Stealth Rock|p1a: Redbull -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|341/386|[from] item: Leftovers -|-heal|p1a: Redbull|365/393|[from] item: Leftovers -|turn|502 -|choice|move 1|move 4 -| -|move|p2a: Heatran|Taunt|p1a: Redbull -|-start|p1a: Redbull|move: Taunt -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|298/386 -| -|-heal|p2a: Heatran|322/386|[from] item: Leftovers -|-heal|p1a: Redbull|389/393|[from] item: Leftovers -|turn|503 -|c| tuxedo_cat|How is it that I was in the wake of 6th gen with a team of birds, and I thrived? -|c| lennylennylenny|502 -|choice|switch 4|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|-damage|p1a: I <3 Stall|264/301|[from] Stealth Rock -|move|p2a: Heatran|Lava Plume|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|170/301 -| -|-heal|p2a: Heatran|346/386|[from] item: Leftovers -|turn|504 -|c| General Zelgius|and at that point he forced like 2-3 counters to check all his different movesets -|c| lennylennylenny|mind games -|c| Amber Torrey|ageislash would even ohko on not very effective hits -|choice|switch 2|move 1 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|362/363 -|-damage|p1a: U Jelly Bruh?|317/363|[from] Stealth Rock -|move|p2a: Heatran|Lava Plume|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|277/363 -|-status|p1a: U Jelly Bruh?|brn -| -|-heal|p1a: U Jelly Bruh?|299/363 brn|[from] item: Black Sludge -|-heal|p2a: Heatran|370/386|[from] item: Leftovers -|-damage|p1a: U Jelly Bruh?|254/363 brn|[from] brn -|turn|505 -|c| tuxedo_cat|And aegislash wasn't the one to make everything else useless. -|c| tuxedo_cat|GRENINJA PROTEAN was. -|c|★Crime♥|finally a burn -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|move 4|switch 3 -| -|switch|p2a: Cobalion|Cobalion|351/386 -|-damage|p2a: Cobalion|339/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|338/386 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|276/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|231/363 brn|[from] brn -|turn|506 -|c|+Jack Dalton|no, aegislash made a lot of things pointless to run -|c| Amber Torrey|Talonflame ageislash and talonflame all go in the same boat for being op -|choice|switch 6|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|276/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: TheMoreYouKnow|Jirachi|371/403 -| -|-heal|p1a: TheMoreYouKnow|396/403|[from] item: Leftovers -|turn|507 -|c| Amber Torrey|greninja* -|c| tuxedo_cat|My talonflame > everyone elses. -|choice|move 2|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-heal|p1a: TheMoreYouKnow|403/403|[from] item: Leftovers -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|508 -|c| tuxedo_cat|Because everyone is an idiot. No offense. -|choice|move 3|switch 5 -| -|switch|p2a: Cobalion|Cobalion|338/386 -|-damage|p2a: Cobalion|326/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|315/386 -|c| tuxedo_cat|Everyone only knows one or two runs for any and all Pokemon. -|c| Amber Torrey|bet it has flare blitz and brave bird tuxedo-cat -|choice|switch 5| -| -|switch|p1a: Annoying AF|Gliscor, M|276/352 tox -| -|-heal|p1a: Annoying AF|320/352 tox|[from] ability: Poison Heal -|turn|509 -|c| tuxedo_cat|Which by all Pokemon, I mean about 12. -|c| Amber Torrey|and maybe bulk up and roost -|c| lennylennylenny|there is mo stall breaker -|c|★Crime♥|gosh -|c|★Crime♥|going to 600 turns -|c|★CHEF BOY4RDEEZNUTS|guess im not sleeping tonight -|choice|move 1|move 4 -| -|move|p1a: Annoying AF|Earthquake|p2a: Cobalion -|-supereffective|p2a: Cobalion -|-damage|p2a: Cobalion|175/386 -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: Redbull|Clefable, M|389/393 -| -|-heal|p1a: Redbull|393/393|[from] item: Leftovers -|turn|510 -|c| Amber Torrey|did i hit the mark Tuxedo_cat? -|choice|move 2|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|370/386 -|-damage|p2a: Heatran|322/386|[from] Stealth Rock -|move|p1a: Redbull|Flamethrower|p2a: Heatran -|-start|p2a: Heatran|ability: Flash Fire -| -|-heal|p2a: Heatran|346/386|[from] item: Leftovers -|turn|511 -|c| tuxedo_cat|Because everyone is convinced to the 9th degree that if they play outside of the box, or if they bring in an underused, they'll lose, or do poorly. -|c| lollity|tuxedo_cat im sure as heck not spending my time memorizing 720 pokemon -|choice|switch 3|move 1 -| -|switch|p1a: Fatty|Chansey, F|531/642 -|move|p2a: Heatran|Lava Plume|p1a: Fatty -|-damage|p1a: Fatty|432/642 -| -|-heal|p2a: Heatran|370/386|[from] item: Leftovers -|turn|512 -|c| lollity|not like i play this game for a living -|choice|move 3|move 4 -| -|move|p2a: Heatran|Taunt|p1a: Fatty -|-start|p1a: Fatty|move: Taunt -|cant|p1a: Fatty|move: Taunt|Wish -| -|-heal|p2a: Heatran|386/386|[from] item: Leftovers -|turn|513 -|c| tuxedo_cat|Not EVERY Pokemon. -|choice|move 1|move 1 -| -|move|p2a: Heatran|Lava Plume|p1a: Fatty -|-damage|p1a: Fatty|336/642 -|-status|p1a: Fatty|brn -|move|p1a: Fatty|Seismic Toss|p2a: Heatran -|-damage|p2a: Heatran|286/386 -| -|-heal|p2a: Heatran|310/386|[from] item: Leftovers -|-damage|p1a: Fatty|256/642 brn|[from] brn -|turn|514 -|c| tuxedo_cat|But try an empoleon. -|c|★CHEF BOY4RDEEZNUTS|im feelin the pressure -|c| lennylennylenny|thats where i see hope -|choice|switch 6|move 1 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|231/363 brn -|move|p2a: Heatran|Lava Plume|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|176/363 brn -| -|-heal|p1a: U Jelly Bruh?|198/363 brn|[from] item: Black Sludge -|-heal|p2a: Heatran|334/386|[from] item: Leftovers -|-damage|p1a: U Jelly Bruh?|153/363 brn|[from] brn -|turn|515 -|c| Amber Torrey|which type of empleon atk or sp.atk? -|c| tuxedo_cat|Try something you don't battle 600 of in the OU tier. -|c|★Crime♥|lmao -|c| tuxedo_cat|Attack for me. -|c|★Crime♥|me too CHEF -|c|★Crime♥|i feel the pressure -|c| tuxedo_cat|Dude... Defiant empoleon can slay gods! -|c| lollity|but -|choice|move 3|switch 3 -| -|-end|p2a: Heatran|ability: Flash Fire|[silent] -|switch|p2a: Cobalion|Cobalion|175/386 -|-damage|p2a: Cobalion|163/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|158/386 -|-ability|p2a: Cobalion|Justified|boost -|-boost|p2a: Cobalion|atk|1 -| -|-heal|p1a: U Jelly Bruh?|175/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|130/363 brn|[from] brn -|turn|516 -|c| lollity|so can other stuff -|c| Amber Torrey|iron head, waterfall, swords dance, aqua jet? -|choice|switch 4|move 3 -| -|switch|p1a: Annoying AF|Gliscor, M|320/352 tox -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|517 -|c| tuxedo_cat|Weakness policy, max special defense... -|choice|switch 6|move 4 -| -|switch|p1a: Fatty|Chansey, F|256/642 -|cant|p2a: Cobalion|slp -| -|turn|518 -|choice|move 4|move 1 -| -|cant|p2a: Cobalion|slp -|move|p1a: Fatty|Heal Bell|p1a: Fatty -|-cureteam|p1a: Fatty|[from] move: HealBell -| -|turn|519 -|c| tuxedo_cat|You will EAT mega manectriks. -|choice|switch 2|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|170/301 -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Close Combat|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|520 -|choice|switch 6|switch 6 -| -|switch|p2a: Chansey|Chansey, F|431/642 -|-damage|p2a: Chansey|351/642|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 -| -|-status|p1a: Annoying AF|tox|[from] item: Toxic Orb -|turn|521 -|choice|switch 2|switch 6 -| -|switch|p1a: Fatty|Chansey, F|256/642 -|switch|p2a: Cobalion|Cobalion|386/386 -|-damage|p2a: Cobalion|374/386|[from] Stealth Rock -| -|turn|522 -|c| tuxedo_cat|Chef... -|choice|switch 2|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|298/352 tox -| -|-heal|p1a: Annoying AF|342/352 tox|[from] ability: Poison Heal -|turn|523 -|c|★CHEF BOY4RDEEZNUTS|ya -|c| tuxedo_cat|Don't switch sableye for chancey. -|c| tuxedo_cat|*from chancey. -|c| tuxedo_cat|It can't kill you. -|choice|move 3|move 4 -| -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|254/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: Redbull|Clefable, M|393/393 -| -|turn|524 -|c| tuxedo_cat|Just run it with calm mind. -|c|★Crime♥|dont believe him -|c| Amber Torrey|Tux -|choice|switch 3|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|334/386 -|-damage|p2a: Heatran|286/386|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|254/352 tox -| -|-heal|p2a: Heatran|310/386|[from] item: Leftovers -|-heal|p1a: Annoying AF|298/352 tox|[from] ability: Poison Heal -|turn|525 -|c| Amber Torrey|what nature on your empoleon? -|c|★Crime♥|oke -|c|★Crime♥|im going to stay -|c| tuxedo_cat|One sec... -|c|★Crime♥|you risk ur last 2pp earthquake? -|c| tuxedo_cat|OH GOD...! -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|move 2|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|293/334 -|-damage|p2a: Skarmory|252/334|[from] Stealth Rock -|move|p1a: Annoying AF|Toxic|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|-heal|p1a: Annoying AF|342/352 tox|[from] ability: Poison Heal -|turn|526 -|c| tuxedo_cat|My teams! -|c| tuxedo_cat|They're gone! -|c|★Crime♥|XD -|c| Amber Torrey|I bet... -|choice|switch 6|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|170/301 -|move|p2a: Skarmory|Whirlwind|p1a: I <3 Stall -|move|p1a: I <3 Stall|Whirlwind|p2a: Skarmory|[from]Magic Bounce -|drag|p2a: Florges|Florges, F|256/360 -|-damage|p2a: Florges|211/360|[from] Stealth Rock -| -|turn|527 -|c| tuxedo_cat|I recently cleared out my cookies... -|c| tuxedo_cat|And I lost my empoleon. -|choice|switch 5|switch 2 -| -|switch|p2a: Heatran|Heatran, F, shiny|310/386 -|-damage|p2a: Heatran|262/386|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-heal|p2a: Heatran|286/386|[from] item: Leftovers -|turn|528 -|c| tuxedo_cat|And my birds... -|c| tuxedo_cat|And my general grevious team... -|c| lollity|empoleon is a bird -|c| tuxedo_cat|Son of a bitch... -|choice|move 2|move 1 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Heatran -|-status|p2a: Heatran|par -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|310/386 par|[from] item: Leftovers -|turn|529 -|c| lollity|im pretty sure -|c| tuxedo_cat|Yes. -|c| tuxedo_cat|He's a penguin. -|c| lollity|yes -|c| lollity|im glad we had this discussion -|c| lennylennylenny|its a pengin -|choice|move 3|move 3 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|297/386 par -|choice|switch 2| -| -|switch|p1a: Fatty|Chansey, F|256/642 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|321/386 par|[from] item: Leftovers -|turn|530 -|c| lennylennylenny|penguin * -|choice|move 3|move 4 -| -|move|p1a: Fatty|Wish|p1a: Fatty -|move|p2a: Heatran|Taunt|p1a: Fatty -|-start|p1a: Fatty|move: Taunt -| -|-heal|p2a: Heatran|345/386 par|[from] item: Leftovers -|turn|531 -|choice|move 1|move 3 -| -|move|p1a: Fatty|Seismic Toss|p2a: Heatran -|-damage|p2a: Heatran|245/386 par -|cant|p2a: Heatran|par -| -|-heal|p1a: Fatty|577/642|[from] move: Wish|[wisher] Fatty -|-heal|p2a: Heatran|269/386 par|[from] item: Leftovers -|turn|532 -|c| Amber Torrey|252+ SpA Mega Manectric Thunderbolt vs. 0 HP / 0+ SpD Empoleon: 302-356 (97.7 - 115.2%) -- 81.3% chance to OHKO -|c| Amber Torrey|eat mega manatric my butt -|c|★Crime♥|lol -|choice|move 1|switch 3 -| -|switch|p2a: Cobalion|Cobalion|374/386 -|-damage|p2a: Cobalion|362/386|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Cobalion -|-damage|p2a: Cobalion|262/386 -| -|turn|533 -|c|★Crime♥|turn 600 pls -|c| Amber Torrey|your empleon would get ohko'ed without a sp.def boosting nature -|choice|switch 6|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|342/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: Redbull|Clefable, M|393/393 -| -|turn|534 -|choice|move 3|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|269/386 par -|-damage|p2a: Heatran|221/386 par|[from] Stealth Rock -|move|p1a: Redbull|Wish|p1a: Redbull -| -|-heal|p2a: Heatran|245/386 par|[from] item: Leftovers -|turn|535 -|choice|switch 4|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|130/363 -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: Fatty|Chansey, F|577/642 -| -|-heal|p1a: Fatty|642/642|[from] move: Wish|[wisher] Redbull -|-heal|p2a: Heatran|269/386 par|[from] item: Leftovers -|turn|536 -|c| Amber Torrey|and a 81 percent chance to get ohkoed with a sp.def nature -|choice|switch 5|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|170/301 -|move|p2a: Heatran|Stealth Rock|p1a: I <3 Stall -|move|p1a: I <3 Stall|Stealth Rock|p2a: Heatran|[from]Magic Bounce -|-fail|p2a: Heatran -| -|-heal|p2a: Heatran|293/386 par|[from] item: Leftovers -|turn|537 -|c| Amber Torrey|empoleon don't eat a mega manatric no matter what -|choice|move 4|switch 6 -| -|switch|p2a: Chansey|Chansey, F|351/642 -|-damage|p2a: Chansey|271/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -| -|turn|538 -|choice|move 3|move 3 -| -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|592/642 -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|512/642 brn|[from] brn -|turn|539 -|c| Amber Torrey|hmmm that made you quite real fast tux... -|choice|move 2|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|293/386 par -|-damage|p2a: Heatran|245/386 par|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|-heal|p2a: Heatran|269/386 par|[from] item: Leftovers -|turn|540 -|choice|move 2|switch 6 -| -|switch|p2a: Chansey|Chansey, F|512/642 -|-damage|p2a: Chansey|432/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|541 -|choice|move 2|move 1 -| -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|542 -|choice|move 3|move 1 -| -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|352/642 brn|[from] brn -|turn|543 -|c| lennylennylenny|this sableye is going places -|c| Amber Torrey|Don't say people are stupid when your trying to block a mega-manatric with a water type -|choice|move 2|move 4 -| -|move|p2a: Chansey|Wish|p2a: Chansey -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|-damage|p2a: Chansey|272/642 brn|[from] brn -|turn|544 -|c| Amber Torrey|those spots go to lanturn and ground types' -|c| Amber Torrey|or lightning roders -|choice|move 2|switch 2 -| -|switch|p2a: Florges|Florges, F|211/360 -|-damage|p2a: Florges|166/360|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|-heal|p2a: Florges|360/360|[from] move: Wish|[wisher] Chansey -|turn|545 -|choice|move 2|switch 2 -| -|switch|p2a: Chansey|Chansey, F|272/642 -|-damage|p2a: Chansey|192/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|546 -|choice|move 3|move 3 -| -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|513/642 -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|433/642 brn|[from] brn -|turn|547 -|c|★Crime♥|hmmm -|c|★Crime♥|its over -|c| Amber Torrey|nah -|c| Amber Torrey|you have a good move -|c| Amber Torrey|not gonna say it tho -|c| tuxedo_cat|Sorry Amber. -|choice|move 2|switch 2 -| -|switch|p2a: Florges|Florges, F|360/360 -|-damage|p2a: Florges|315/360|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-fail|p1a: I <3 Stall -| -|turn|548 -|c| lollity|what turn number is this -|c| tuxedo_cat|I've been away for a sec. -|choice|move 4|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-fail|p1a: I <3 Stall -| -|turn|549 -|c| Amber Torrey|548 -|c| lollity|k -|c| tuxedo_cat|What were you saying? -|choice|move 3|switch 2 -| -|switch|p2a: Chansey|Chansey, F|433/642 -|-damage|p2a: Chansey|353/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|273/642 brn|[from] brn -|turn|550 -|c| Amber Torrey|wish to know look up not repeating myself -|choice|switch 5|switch 2 -| -|switch|p2a: Florges|Florges, F|315/360 -|-damage|p2a: Florges|270/360|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|642/642 -| -|turn|551 -|c| tuxedo_cat|I'm not even kidding when I say that a high special defense empoleon can tank t-bolts. -|choice|move 3|move 4 -| -|move|p2a: Florges|Wish|p2a: Florges -|move|p1a: Fatty|Wish|p1a: Fatty -| -|turn|552 -|choice|switch 6|switch 2 -| -|switch|p2a: Chansey|Chansey, F|273/642 -|-damage|p2a: Chansey|193/642|[from] Stealth Rock -|switch|p1a: U Jelly Bruh?|Tentacruel, M|130/363 -| -|-heal|p2a: Chansey|373/642|[from] move: Wish|[wisher] Florges -|-heal|p1a: U Jelly Bruh?|363/363|[from] move: Wish|[wisher] Fatty -|turn|553 -|c| lollity|but -|c| lollity|so can latias -|c| tuxedo_cat|I'm probably going to use this unfortunate opportunity to experiment. -|choice|move 4|switch 3 -| -|switch|p2a: Cobalion|Cobalion|262/386 -|-damage|p2a: Cobalion|250/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|247/386 -| -|turn|554 -|c|★Crime♥|knock off my chansey idc anymore -|c|★Crime♥|it has no heals left -|c|★Crime♥|:( -|choice|switch 3|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|342/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: Redbull|Clefable, M|393/393 -| -|turn|555 -|c| Amber Torrey|252+ SpA Mega Manectric Thunderbolt vs. 0 HP / 0 SpD Empoleon: 330-390 (106.7 - 126.2%) -- guaranteed OHKO empoleon gets 100 percent ohko'ed with a sp.def boosting nature -|c| Amber Torrey|and with one it's a 81 percent ohko rate -|choice|switch 4|switch 2 -| -|switch|p2a: Florges|Florges, F|270/360 -|-damage|p2a: Florges|225/360|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|342/352 tox -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|556 -|c| Amber Torrey|empoleon can not tank mega-manatric -|choice|move 2|switch 4 -| -|switch|p2a: Skarmory|Skarmory, F|252/334 -|-damage|p2a: Skarmory|211/334|[from] Stealth Rock -|move|p1a: Annoying AF|Toxic|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|557 -|c| Amber Torrey|without* -|c|★Crime♥|emopoleon sux -|c|★Crime♥|for offensive and stall. -|c|★Crime♥|lol -|c| Amber Torrey|empoleon is so so -|c|★Crime♥|600 turns -|c|★Crime♥|pls -|c| Amber Torrey|but blocking eletric attacks from the strongest electric type -|choice|switch 5|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Skarmory|Defog|p1a: I <3 Stall -|move|p1a: I <3 Stall|Defog|p2a: Skarmory|[from]Magic Bounce -|-unboost|p2a: Skarmory|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|558 -|c| Amber Torrey|not a chance in hell -|c| tuxedo_cat|Jolteons... -|c| Amber Torrey|are way weaker -|c| tuxedo_cat|Thunderous... -|c| tuxedo_cat|Nah. -|choice|switch 2|switch 2 -| -|switch|p2a: Cobalion|Cobalion|247/386 -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|turn|559 -|c| Amber Torrey|still weaker -|c|★CHEF BOY4RDEEZNUTS|last defog -|c| tuxedo_cat|My empoleon can't take those. -|choice|move 4|move 2 -| -|move|p2a: Cobalion|Iron Head|p1a: TheMoreYouKnow -|-resisted|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|361/403 -|cant|p1a: TheMoreYouKnow|flinch -| -|-heal|p1a: TheMoreYouKnow|386/403|[from] item: Leftovers -|turn|560 -|c|★Crime♥|no rocks -|c| tuxedo_cat|Earthquakes, no chance in hell. -|choice|move 4|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|269/386 par -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Heatran -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|403/403|[from] item: Leftovers -|-heal|p2a: Heatran|293/386 par|[from] item: Leftovers -|turn|561 -|choice|move 3|move 3 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|279/386 par -|choice|switch 2| -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Stealth Rock|p1a: I <3 Stall -|move|p1a: I <3 Stall|Stealth Rock|p2a: Heatran|[from]Magic Bounce -|-fail|p2a: Heatran -| -|-heal|p2a: Heatran|303/386 par|[from] item: Leftovers -|turn|562 -|choice|move 2|move 2 -| -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -|move|p2a: Heatran|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Heatran|[from]Magic Bounce -|drag|p2a: Cobalion|Cobalion|247/386 -|-damage|p2a: Cobalion|235/386|[from] Stealth Rock -| -|turn|563 -|c| Amber Torrey|probably the reason you can't take a jolteon or thunderus is because of choiice specs -|c| tuxedo_cat|For jolteon, maybe. -|c|★CHEF BOY4RDEEZNUTS|jolteon is awesome -|choice|move 1|switch 4 -| -|switch|p2a: Florges|Florges, F|225/360 -|-damage|p2a: Florges|180/360|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Florges -|-damage|p2a: Florges|117/360 -| -|turn|564 -|c| Amber Torrey|no matter what empoleon can't eletric types man -|c| tuxedo_cat|But megatrics typically leave me at about 20%, give or take. -|c| tuxedo_cat|But when they mega evolve... -|choice|switch 5|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Florges|Wish|p2a: Florges -| -|turn|565 -|c| tuxedo_cat|That sets off defiant. -|choice|move 3|move 2 -| -|move|p2a: Florges|Protect|p2a: Florges -|-singleturn|p2a: Florges|Protect -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|264/352 tox -| -|-heal|p2a: Florges|297/360|[from] move: Wish|[wisher] Florges -|-heal|p1a: Annoying AF|308/352 tox|[from] ability: Poison Heal -|turn|566 -|c| lollity|yeah bu -|c| lollity|it wont do you much good if youre dead -|c| tuxedo_cat|Then, I survive t-bolt and get weakness policy. -|c|★CHEF BOY4RDEEZNUTS|lol -|c| Amber Torrey|252+ SpA Mega Manectric Thunderbolt vs. 0 HP / 0+ SpD Empoleon: 302-356 (97.7 - 115.2%) -- 81.3% chance to OHKO 20 percent left hp my left nut -|choice|move 2|switch 2 -| -|switch|p2a: Skarmory|Skarmory, F|211/334 -|-damage|p2a: Skarmory|170/334|[from] Stealth Rock -|move|p1a: Annoying AF|Toxic|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|567 -|c| lollity|plus -|c| Amber Torrey|your have lower then 3 percent -|c| lollity|doesnt it still outspeed you -|c| Amber Torrey|if your lucky -|c| lollity|? -|choice|switch 2|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|334/334 -| -|turn|568 -|c|★Crime♥|5 rocks -|c|★Crime♥|not bad -|c| tuxedo_cat|I guess I've been lucky for 3 years then. -|choice|move 2|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|569 -|c| lollity|i guess so -|c| lollity|:P -|choice|move 3|move 1 -| -|move|p1a: TheMoreYouKnow|U-turn|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-crit|p2a: Slowbro -|-damage|p2a: Slowbro|177/394 tox -|c| Amber Torrey|your just a big liar for 3 years -|c|★Crime♥|oh guys wait -|c|★CHEF BOY4RDEEZNUTS|ooof lol -|c|★Crime♥|we still have mega slowbro -|choice|switch 6| -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Slowbro|Scald|p1a: Fatty -|-damage|p1a: Fatty|596/642 -| -|-damage|p2a: Slowbro|129/394 tox|[from] psn -|turn|570 -|c| Amber Torrey|because calcs don't lie -|c|★CHEF BOY4RDEEZNUTS|hes posioned doe -|c|★CHEF BOY4RDEEZNUTS|poisoned -|c|★Crime♥|we will heal slowbro -|choice|move 1|switch 4 -| -|switch|p2a: Cobalion|Cobalion|235/386 -|-damage|p2a: Cobalion|223/386|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Cobalion -|-damage|p2a: Cobalion|123/386 -| -|turn|571 -|c|★Crime♥|dont worry -|c| lollity|can he just jkeep switching out with reggenerator -|c|★Crime♥|i have a hidden move -|c| lollity|to heal to full -|c|★CHEF BOY4RDEEZNUTS|not when hes mega -|choice|switch 5|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|turn|572 -|choice|move 2|move 4 -| -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -|cant|p2a: Cobalion|slp -| -|turn|573 -|choice|move 2|move 4 -| -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -|cant|p2a: Cobalion|slp -| -|turn|574 -|c| Amber Torrey|I think there needs to be a sp.atk verson of foul play -|c| Amber Torrey|but fairy typing -|c|★CHEF BOY4RDEEZNUTS|that would be dope -|choice|move 3|move 2 -| -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Iron Head|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|244/301 -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Cobalion -|-status|p2a: Cobalion|brn -| -|-damage|p2a: Cobalion|338/386 brn|[from] brn -|turn|575 -|c|★CHEF BOY4RDEEZNUTS|YUSSSSSS -|c|★CHEF BOY4RDEEZNUTS|until he rests -|choice|move 2|switch 3 -| -|switch|p2a: Chansey|Chansey, F|373/642 -|-damage|p2a: Chansey|293/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|576 -|c|★Crime♥|it has rest remember -|choice|move 2|switch 3 -| -|switch|p2a: Cobalion|Cobalion|338/386 brn -|-damage|p2a: Cobalion|326/386 brn|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|-damage|p2a: Cobalion|278/386 brn|[from] brn -|turn|577 -|choice|move 1|switch 3 -| -|switch|p2a: Chansey|Chansey, F|293/642 -|-damage|p2a: Chansey|213/642|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Chansey -|-immune|p2a: Chansey|[msg] -| -|turn|578 -|c|★Crime♥|tricking you a bit -|choice|move 3|move 4 -| -|move|p2a: Chansey|Wish|p2a: Chansey -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|133/642 brn|[from] brn -|turn|579 -|c|★CHEF BOY4RDEEZNUTS|no moar wishes -|choice|move 2|move 1 -| -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|-heal|p2a: Chansey|454/642 brn|[from] move: Wish|[wisher] Chansey -|-damage|p2a: Chansey|374/642 brn|[from] brn -|turn|580 -|choice|move 4|switch 2 -| -|switch|p2a: Florges|Florges, F|297/360 -|-damage|p2a: Florges|252/360|[from] Stealth Rock -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -| -|turn|581 -|c| Amber Torrey|hmmm no toxic on chansey? -|c|★Crime♥|i do -|c|★CHEF BOY4RDEEZNUTS|same -|c|★CHEF BOY4RDEEZNUTS|magic bounce -|c|★CHEF BOY4RDEEZNUTS|tho -|c| Amber Torrey|right -|choice|switch 5|move 1 -| -|switch|p1a: Fatty|Chansey, F|596/642 -|move|p2a: Florges|Moonblast|p1a: Fatty -|-damage|p1a: Fatty|538/642 -|-unboost|p1a: Fatty|spa|1 -| -|turn|582 -|c| Amber Torrey|forgot sableye in general is a dbag -|c|★Crime♥|omg -|c|★Crime♥|600 turns -|c|★Crime♥|we will made it -|c|★CHEF BOY4RDEEZNUTS|oh no not my sp attack lol -|choice|move 3|switch 3 -| -|switch|p2a: Cobalion|Cobalion|278/386 brn -|-damage|p2a: Cobalion|266/386 brn|[from] Stealth Rock -|move|p1a: Fatty|Wish|p1a: Fatty -| -|-damage|p2a: Cobalion|218/386 brn|[from] brn -|turn|583 -|choice|switch 2|move 3 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|turn|584 -|choice|move 3|move 4 -| -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|264/352 tox -|cant|p2a: Cobalion|slp -| -|-heal|p1a: Annoying AF|308/352 tox|[from] ability: Poison Heal -|turn|585 -|choice|move 4|move 4 -| -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-singleturn|p1a: Annoying AF|Protect -|cant|p2a: Cobalion|slp -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|586 -|c| Amber Torrey|ah the typiical gliscor set sub,protect,toxic,equake -|choice|move 2|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|334/334 -|-damage|p2a: Skarmory|293/334|[from] Stealth Rock -|move|p1a: Annoying AF|Toxic|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|587 -|c| Amber Torrey|why toxic? -|c|★CHEF BOY4RDEEZNUTS|i love stalling rotom w with it -|c| Amber Torrey|cabolion is steel typing to -|c|★CHEF BOY4RDEEZNUTS|pp bro -|c|★CHEF BOY4RDEEZNUTS|least useful more for him rn -|c|★CHEF BOY4RDEEZNUTS|move -|choice|switch 6|switch 5 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Cobalion|Cobalion|386/386 slp -|-damage|p2a: Cobalion|374/386 slp|[from] Stealth Rock -| -|turn|588 -|c| Amber Torrey|hmmm you do have 3 steel types kinda makes gliscor useless -|c| Amber Torrey|and a skarmory for his equakes -|c|★Crime♥|we are battling for 3 hours.. -|c|★Crime♥|i want to smoke -|choice|move 3|move 2 -| -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Iron Head|p1a: TheMoreYouKnow -|-resisted|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|364/403 -|move|p1a: TheMoreYouKnow|U-turn|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|364/386 -|c|★CHEF BOY4RDEEZNUTS|3 hours oh my lol -|choice|switch 5| -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|turn|589 -|c| Amber Torrey|This is why I think tournament rules need to be put in the game -|choice|switch 6|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|301/352 tox -| -|-heal|p1a: Annoying AF|345/352 tox|[from] ability: Poison Heal -|turn|590 -|c| Amber Torrey|after 75 turns both teams both auto lose -|c|★CHEF BOY4RDEEZNUTS|someone on AG awhile back was using 6 klefkis -|c|★Crime♥|lol -|c|★CHEF BOY4RDEEZNUTS|lasted probs as long as this battle -|choice|switch 6|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Cobalion|[from]Magic Bounce -|drag|p2a: Heatran|Heatran, F, shiny|303/386 par -|-damage|p2a: Heatran|255/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|279/386 par|[from] item: Leftovers -|turn|591 -|c|★Crime♥|1 bisharp -|c|★Crime♥|and its over -|c|★CHEF BOY4RDEEZNUTS|with all the full paras -|choice|switch 6|move 1 -| -|switch|p1a: Annoying AF|Gliscor, M|345/352 tox -|move|p2a: Heatran|Lava Plume|p1a: Annoying AF -|-damage|p1a: Annoying AF|209/352 tox -| -|-heal|p2a: Heatran|303/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|253/352 tox|[from] ability: Poison Heal -|turn|592 -|choice|move 1|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|260/394 tox -|-damage|p2a: Slowbro|211/394 tox|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Slowbro -|-damage|p2a: Slowbro|138/394 tox -| -|-heal|p1a: Annoying AF|297/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|114/394 tox|[from] psn -|turn|593 -|choice|switch 3|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Skarmory|Skarmory, F|293/334 -|-damage|p2a: Skarmory|252/334|[from] Stealth Rock -| -|turn|594 -|c| Amber Torrey|was that the last equake? -|choice|move 1|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|245/394 tox -|-damage|p2a: Slowbro|196/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Scald|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|146/394 tox -| -|-damage|p2a: Slowbro|122/394 tox|[from] psn -|turn|595 -|c|★Crime♥|1 left -|c|★CHEF BOY4RDEEZNUTS|1 more left -|c|★CHEF BOY4RDEEZNUTS|last scald doe -|choice|move 2|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|252/334 -|-damage|p2a: Skarmory|211/334|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Skarmory -|-immune|p2a: Skarmory|[msg] -| -|turn|596 -|choice|switch 3|switch 5 -| -|switch|p1a: Annoying AF|Gliscor, M|297/352 tox -|switch|p2a: Slowbro|Slowbro, F|253/394 tox -|-damage|p2a: Slowbro|204/394 tox|[from] Stealth Rock -| -|-heal|p1a: Annoying AF|341/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|180/394 tox|[from] psn -|turn|597 -|choice|switch 3|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Skarmory|Skarmory, F|211/334 -|-damage|p2a: Skarmory|170/334|[from] Stealth Rock -| -|turn|598 -|choice|move 3|move 1 -| -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Skarmory -|-damage|p2a: Skarmory|152/334 -|move|p2a: Skarmory|Brave Bird|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|195/363 -|-damage|p2a: Skarmory|97/334|[from] recoil|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|217/363|[from] item: Black Sludge -|turn|599 -|choice|switch 6|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|264/334 -| -|turn|600 -|choice|switch 2|switch 6 -| -|switch|p2a: Cobalion|Cobalion|364/386 -|-damage|p2a: Cobalion|352/386|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|538/642 -| -|turn|601 -|c|★Crime♥|omg 600+ -|c|★Crime♥|im gonna put it in lobby chat -|c|★CHEF BOY4RDEEZNUTS|lol -|c| tuxedo_cat|...Jesus Chroist people! It's still going? -|c| Amber Torrey|hmm so defense is higher -|c|★Crime♥|lol -|c|★CHEF BOY4RDEEZNUTS|and no kills....lol -|choice|switch 3|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|341/352 tox -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|284/352 tox -| -|-heal|p1a: Annoying AF|328/352 tox|[from] ability: Poison Heal -|turn|602 -|c| Amber Torrey|meh just two stall teams fighting each other -|choice|move 2|move 2 -| -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|277/352 tox -|move|p1a: Annoying AF|Toxic|p2a: Cobalion -|-immune|p2a: Cobalion|[msg] -| -|-heal|p1a: Annoying AF|321/352 tox|[from] ability: Poison Heal -|turn|603 -|choice|move 3|move 2 -| -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|269/352 tox -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|181/352 tox -| -|-heal|p1a: Annoying AF|225/352 tox|[from] ability: Poison Heal -|turn|604 -|choice|move 4|move 2 -| -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-singleturn|p1a: Annoying AF|Protect -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-activate|p1a: Annoying AF|Protect -| -|-heal|p1a: Annoying AF|269/352 tox|[from] ability: Poison Heal -|turn|605 -|c| Amber Torrey|darn -|c| Amber Torrey|you need some iron head flinches -|choice|move 1|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|311/394 tox -|-damage|p2a: Slowbro|262/394 tox|[from] Stealth Rock -|move|p1a: Annoying AF|Earthquake|p2a: Slowbro -|-damage|p2a: Slowbro|190/394 tox -| -|-heal|p1a: Annoying AF|313/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|166/394 tox|[from] psn -|turn|606 -|c| Santeyan|what the actual f-ck is this game -|c| Amber Torrey|a battle between two full stall teams -|choice|move 2|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|303/386 par -|-damage|p2a: Heatran|255/386 par|[from] Stealth Rock -|move|p1a: Annoying AF|Toxic|p2a: Heatran -|-fail|p2a: Heatran -| -|-heal|p2a: Heatran|279/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|607 -|c| Santeyan|how many hours has it been? -|c|★Crime♥|no earthquakes -|c|★Crime♥|XD -|c|★CHEF BOY4RDEEZNUTS|no eqs :( -|c|★Crime♥|3 hours and 20 mins+ -|choice|switch 6|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|217/363 -|move|p2a: Heatran|Stealth Rock|p1a: U Jelly Bruh? -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|239/363|[from] item: Black Sludge -|-heal|p2a: Heatran|303/386 par|[from] item: Leftovers -|turn|608 -|choice|move 4|switch 5 -| -|switch|p2a: Cobalion|Cobalion|352/386 -|-damage|p2a: Cobalion|340/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|337/386 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|261/363|[from] item: Black Sludge -|turn|609 -|c| Amber Torrey|I made a pure competitive team irl for pokemon ORAS in that team -|c|★Crime♥|luckily -|c| Amber Torrey|geez -|c| General Zelgius|wow -|c|★Crime♥|i still have a defog -|c| General Zelgius|nothing died? -|c|★CHEF BOY4RDEEZNUTS|i have 5 rocks lol -|choice|switch 6|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|297/394 tox -|-damage|p2a: Slowbro|248/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-damage|p2a: Slowbro|224/394 tox|[from] psn -|turn|610 -|c|★Crime♥|5 rocks -|c|★Crime♥|lel -|choice|move 3|switch 4 -| -|switch|p2a: Cobalion|Cobalion|337/386 -|-damage|p2a: Cobalion|325/386|[from] Stealth Rock -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|264/352 tox -| -|-heal|p1a: Annoying AF|308/352 tox|[from] ability: Poison Heal -|turn|611 -|c| Amber Torrey|If this does come down to no pp and swap stalling alone -|choice|move 2|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|355/394 tox -|-damage|p2a: Slowbro|306/394 tox|[from] Stealth Rock -|move|p1a: Annoying AF|Toxic|p2a: Slowbro -|-fail|p2a: Slowbro|tox -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|282/394 tox|[from] psn -|turn|612 -|c| Amber Torrey|i will call down a higher up to end this -|c| Juggerton|lol -|c|★CHEF BOY4RDEEZNUTS|i have rocks on the field at least -|c|★Crime♥|lol -|c| lollity|jesus -|choice|switch 6|switch 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|261/363 -|switch|p2a: Cobalion|Cobalion|325/386 -|-damage|p2a: Cobalion|313/386|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|283/363|[from] item: Black Sludge -|turn|613 -|c| Amber Torrey|because it would no longer be a legit 600+ rounds game -|choice|switch 2|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|614 -|c| Amber Torrey|would be just two people swap stalling -|c|★Crime♥|it will be legit -|c| Amber Torrey|which anyone can do -|c|★Crime♥|till this game has finished -|choice|move 3|switch 4 -| -|switch|p2a: Cobalion|Cobalion|313/386 -|-damage|p2a: Cobalion|301/386|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Cobalion -|-status|p2a: Cobalion|brn -| -|-damage|p2a: Cobalion|253/386 brn|[from] brn -|turn|615 -|c| Santeyan|I saw a guy called I AM NOT STALLING set the record on showdown with a 402 turn battle -|c| Santeyan|his record got destroyed -|choice|move 1|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: I <3 Stall|Shadow Ball|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|159/394 tox -| -|-damage|p2a: Slowbro|135/394 tox|[from] psn -|turn|616 -|choice|move 3|switch 4 -| -|switch|p2a: Cobalion|Cobalion|253/386 brn -|-damage|p2a: Cobalion|241/386 brn|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Cobalion|[miss] -|-miss|p1a: I <3 Stall|p2a: Cobalion -| -|-damage|p2a: Cobalion|193/386 brn|[from] brn -|turn|617 -|c|★Crime♥|her* -|c| Amber Torrey|saw people with 2k plus round matches just turn stalling -|c| Santeyan|i have to go to school, but i want to watch this :'( -|c|★Crime♥|and thats me btw santeyan -|c|★Crime♥|my stalling skills got improved -|c|★Crime♥|xD -|c| Santeyan|nice :) -|choice|switch 5|move 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|364/403 -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|-heal|p1a: TheMoreYouKnow|389/403|[from] item: Leftovers -|turn|618 -|c| Santeyan|gtg, bye -|c|★Crime♥|bye -|c| Amber Torrey|so as soon as this turns into to a turn stall probably just gonna leave no longer legit at that point -|c|★CHEF BOY4RDEEZNUTS|2 rests left -|c|★Crime♥|rip rest -|choice|switch 2|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|283/363 -|cant|p2a: Cobalion|slp -| -|-heal|p1a: U Jelly Bruh?|305/363|[from] item: Black Sludge -|turn|619 -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|383/386 slp -|cant|p2a: Cobalion|slp -| -|-heal|p1a: U Jelly Bruh?|327/363|[from] item: Black Sludge -|turn|620 -|c|★CHEF BOY4RDEEZNUTS|1 percent -|c|★CHEF BOY4RDEEZNUTS|the power -|choice|switch 6|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|266/394 tox -|-damage|p2a: Slowbro|217/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-damage|p2a: Slowbro|193/394 tox|[from] psn -|turn|621 -|c|★Crime♥|im suprised it does 1% though -|choice|move 2|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|303/386 par -|-damage|p2a: Heatran|255/386 par|[from] Stealth Rock -|move|p1a: Annoying AF|Toxic|p2a: Heatran -|-fail|p2a: Heatran -| -|-heal|p2a: Heatran|279/386 par|[from] item: Leftovers -|turn|622 -|choice|move 2|move 3 -| -|move|p1a: Annoying AF|Toxic|p2a: Heatran -|-fail|p2a: Heatran -|move|p2a: Heatran|Stealth Rock|p1a: Annoying AF -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|303/386 par|[from] item: Leftovers -|turn|623 -|choice|switch 6|move 1 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|327/363 -|-damage|p1a: U Jelly Bruh?|282/363|[from] Stealth Rock -|move|p2a: Heatran|Lava Plume|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|242/363 -|-status|p1a: U Jelly Bruh?|brn -| -|-heal|p1a: U Jelly Bruh?|264/363 brn|[from] item: Black Sludge -|-heal|p2a: Heatran|327/386 par|[from] item: Leftovers -|-damage|p1a: U Jelly Bruh?|219/363 brn|[from] brn -|turn|624 -|c|★Crime♥|yes burn -|c| Amber Torrey|woohoo burned -|c| lollity|jeez man -|choice|move 4|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|324/394 tox -|-damage|p2a: Slowbro|275/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|271/394 tox -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|241/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|196/363 brn|[from] brn -|-damage|p2a: Slowbro|247/394 tox|[from] psn -|turn|625 -|c| lollity|are you guys out of heal bells? -|c|★CHEF BOY4RDEEZNUTS|i got sum -|c|★Crime♥|i am -|choice|switch 3|switch 4 -| -|switch|p1a: Fatty|Chansey, F|538/642 -|switch|p2a: Cobalion|Cobalion|383/386 slp -|-damage|p2a: Cobalion|371/386 slp|[from] Stealth Rock -| -|turn|626 -|c|★Crime♥|1 left -|c|★Crime♥|heal bell -|c|★Crime♥|:P -|choice|switch 5|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Cobalion|[from]Magic Bounce -|drag|p2a: Slowbro|Slowbro, F|378/394 tox -|-damage|p2a: Slowbro|329/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|305/394 tox|[from] psn -|turn|627 -|choice|switch 5|switch 4 -| -|switch|p2a: Cobalion|Cobalion|371/386 -|-damage|p2a: Cobalion|359/386|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|538/642 -| -|turn|628 -|choice|switch 6|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|629 -|choice|switch 4|switch 4 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|switch|p2a: Cobalion|Cobalion|359/386 -|-damage|p2a: Cobalion|347/386|[from] Stealth Rock -| -|turn|630 -|c|★Crime♥|will we hit 700 -|choice|switch 2|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|327/386 par -|-damage|p2a: Heatran|279/386 par|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|389/403 -| -|-heal|p1a: TheMoreYouKnow|403/403|[from] item: Leftovers -|-heal|p2a: Heatran|303/386 par|[from] item: Leftovers -|turn|631 -|c| Amber Torrey|probably i mean your just switch stalling... -|choice|move 2|switch 5 -| -|switch|p2a: Cobalion|Cobalion|347/386 -|-damage|p2a: Cobalion|335/386|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Cobalion -|-status|p2a: Cobalion|par -| -|turn|632 -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|255/394 tox -|c|★Crime♥|well we have to -|choice|switch 2| -| -|switch|p1a: Redbull|Clefable, M|393/393 -| -|-damage|p2a: Slowbro|231/394 tox|[from] psn -|turn|633 -|c|★Crime♥|dont we -|choice|move 1|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|303/386 par -|-damage|p2a: Heatran|255/386 par|[from] Stealth Rock -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|234/386 par -| -|-heal|p2a: Heatran|258/386 par|[from] item: Leftovers -|turn|634 -|choice|switch 6|move 3 -| -|switch|p1a: Fatty|Chansey, F|538/642 -|move|p2a: Heatran|Stealth Rock|p1a: Fatty -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|282/386 par|[from] item: Leftovers -|turn|635 -|choice|move 4|move 4 -| -|move|p1a: Fatty|Heal Bell|p1a: Fatty -|-cureteam|p1a: Fatty|[from] move: HealBell -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|306/386 par|[from] item: Leftovers -|turn|636 -|c| Amber Torrey|you don't "have" to do anything -|c| Amber Torrey|your choose to -|c| Amber Torrey|you* -|choice|move 1|move 4 -| -|move|p1a: Fatty|Seismic Toss|p2a: Heatran -|-damage|p2a: Heatran|206/386 par -|move|p2a: Heatran|Taunt|p1a: Fatty -|-start|p1a: Fatty|move: Taunt -| -|-heal|p2a: Heatran|230/386 par|[from] item: Leftovers -|turn|637 -|choice|move 1|switch 4 -| -|switch|p2a: Cobalion|Cobalion|335/386 par -|-damage|p2a: Cobalion|323/386 par|[from] Stealth Rock -|move|p1a: Fatty|Seismic Toss|p2a: Cobalion -|-damage|p2a: Cobalion|223/386 par -| -|turn|638 -|choice|switch 4|switch 5 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 -|-damage|p1a: Annoying AF|308/352|[from] Stealth Rock -|switch|p2a: Slowbro|Slowbro, F|362/394 tox -|-damage|p2a: Slowbro|313/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|289/394 tox|[from] psn -|-status|p1a: Annoying AF|tox|[from] item: Toxic Orb -|turn|639 -|c|★Crime♥|out of Seis -|choice|move 4|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|230/386 par -|-damage|p2a: Heatran|182/386 par|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p2a: Heatran|206/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|640 -|choice|move 3|move 4 -| -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|264/352 tox -|move|p2a: Heatran|Taunt|p1a: Annoying AF -|-start|p1a: Annoying AF|move: Taunt -| -|-heal|p2a: Heatran|230/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|308/352 tox|[from] ability: Poison Heal -|turn|641 -|c| Amber Torrey|hmm both opponents only have one physical attacker no wonder chansey has never died... -|c|★Crime♥|lol -|choice|move 1|move 3 -| -|-activate|p1a: Annoying AF|move: Struggle -|move|p1a: Annoying AF|Struggle|p2a: Heatran -|-damage|p2a: Heatran|201/386 par -|-damage|p1a: Annoying AF|220/352 tox|[from] recoil -|move|p2a: Heatran|Stealth Rock|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p2a: Heatran|225/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|264/352 tox|[from] ability: Poison Heal -|turn|642 -|choice|move 1|move 4 -| -|-activate|p1a: Annoying AF|move: Struggle -|move|p1a: Annoying AF|Struggle|p2a: Heatran -|-damage|p2a: Heatran|193/386 par -|-damage|p1a: Annoying AF|176/352 tox|[from] recoil -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|217/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|220/352 tox|[from] ability: Poison Heal -|turn|643 -|c| Amber Torrey|don't waste stealth rocks -|c|★CHEF BOY4RDEEZNUTS|struggle has no pp XD -|choice|move 1|move 2 -| -|-activate|p1a: Annoying AF|move: Struggle -|move|p1a: Annoying AF|Struggle|p2a: Heatran -|-damage|p2a: Heatran|184/386 par -|-damage|p1a: Annoying AF|132/352 tox|[from] recoil -|move|p2a: Heatran|Roar|p1a: Annoying AF -|drag|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|-damage|p1a: I <3 Stall|264/301|[from] Stealth Rock -| -|-heal|p2a: Heatran|208/386 par|[from] item: Leftovers -|turn|644 -|choice|move 4|move 4 -| -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -|move|p2a: Heatran|Taunt|p1a: I <3 Stall -|move|p1a: I <3 Stall|Taunt|p2a: Heatran|[from]Magic Bounce -|-start|p2a: Heatran|move: Taunt -| -|-heal|p2a: Heatran|232/386 par|[from] item: Leftovers -|turn|645 -|choice|switch 4|move 1 -| -|switch|p1a: Fatty|Chansey, F|538/642 -|-damage|p1a: Fatty|458/642|[from] Stealth Rock -|move|p2a: Heatran|Lava Plume|p1a: Fatty -|-damage|p1a: Fatty|392/642 -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|turn|646 -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: Fatty|Wish|p1a: Fatty -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|647 -|c|★Crime♥|700 turns pls -|c|★CHEF BOY4RDEEZNUTS|sleep pls -|c|★CHEF BOY4RDEEZNUTS|lol -|choice|move 2|move 1 -| -|move|p1a: Fatty|Toxic|p2a: Slowbro|[miss] -|-miss|p1a: Fatty|p2a: Slowbro -|move|p2a: Slowbro|Scald|p1a: Fatty -|-damage|p1a: Fatty|346/642 -| -|-heal|p1a: Fatty|642/642|[from] move: Wish|[wisher] Fatty -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|648 -|choice|switch 3|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|196/363 -|-damage|p1a: U Jelly Bruh?|151/363|[from] Stealth Rock -|switch|p2a: Cobalion|Cobalion|223/386 par -|-damage|p2a: Cobalion|211/386 par|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|173/363|[from] item: Black Sludge -|turn|649 -|choice|move 4|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|337/394 tox -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|195/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|313/394 tox|[from] psn -|turn|650 -|choice|move 3|switch 5 -| -|switch|p2a: Cobalion|Cobalion|211/386 par -|-damage|p2a: Cobalion|199/386 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|188/386 par -|-ability|p2a: Cobalion|Justified|boost -|-boost|p2a: Cobalion|atk|1 -| -|-heal|p1a: U Jelly Bruh?|217/363|[from] item: Black Sludge -|turn|651 -|choice|switch 5|switch 5 -| -|switch|p1a: Annoying AF|Gliscor, M|132/352 tox -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: Annoying AF|176/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|652 -|c| tuxedo_cat|... -|c| tuxedo_cat|Oh... -|c| tuxedo_cat|650 moves... -|choice|move 4|switch 5 -| -|switch|p2a: Cobalion|Cobalion|188/386 par -|-damage|p2a: Cobalion|176/386 par|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p1a: Annoying AF|220/352 tox|[from] ability: Poison Heal -|turn|653 -|c|★Crime♥|lol -|c| tuxedo_cat|What left is there? -|choice|move 4|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p1a: Annoying AF|264/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|654 -|c|★Crime♥|lmao -|c|★Crime♥|only sub and protect left -|c| tuxedo_cat|Yeesh. Slowbro still has a lot going. -|c|★Crime♥|useless pok -|c|★Crime♥|xD -|choice|switch 3|switch 5 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Cobalion|Cobalion|176/386 par -|-damage|p2a: Cobalion|164/386 par|[from] Stealth Rock -| -|turn|655 -|c|★CHEF BOY4RDEEZNUTS|it still walls cob -|choice|switch 3|switch 5 -| -|switch|p1a: Annoying AF|Gliscor, M|264/352 tox -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: Annoying AF|308/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|656 -|choice|switch 5|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|217/363 -|switch|p2a: Cobalion|Cobalion|164/386 par -|-damage|p2a: Cobalion|152/386 par|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|239/363|[from] item: Black Sludge -|turn|657 -|choice|move 3|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-crit|p2a: Slowbro -|-damage|p2a: Slowbro|273/394 tox -| -|-heal|p1a: U Jelly Bruh?|261/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|249/394 tox|[from] psn -|turn|658 -|c|★Crime♥|crit mattered -|c|★CHEF BOY4RDEEZNUTS|switch after switch after switch -|choice|move 4|switch 5 -| -|switch|p2a: Cobalion|Cobalion|152/386 par -|-damage|p2a: Cobalion|140/386 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|137/386 par -| -|-heal|p1a: U Jelly Bruh?|283/363|[from] item: Black Sludge -|turn|659 -|choice|move 2|move 3 -| -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Cobalion -|-immune|p2a: Cobalion|[msg] -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|-heal|p1a: U Jelly Bruh?|305/363|[from] item: Black Sludge -|turn|660 -|c|★Crime♥|+2 free turns -|c|★Crime♥|XD -|choice|switch 6|move 4 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|cant|p2a: Cobalion|slp -| -|turn|661 -|choice|move 4|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|256/386 par -|-damage|p2a: Heatran|208/386 par|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|232/386 par|[from] item: Leftovers -|turn|662 -|choice|move 1|move 2 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|198/386 par -|move|p2a: Heatran|Roar|p1a: Redbull -|drag|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|-heal|p2a: Heatran|222/386 par|[from] item: Leftovers -|turn|663 -|c|★Crime♥|if heatran had no leftovers -|c|★CHEF BOY4RDEEZNUTS|tell me about it... -|c|★Crime♥|it was 300 turns earlier already over -|choice|move 1|move 3 -| -|move|p1a: I <3 Stall|Shadow Ball|p2a: Heatran -|-damage|p2a: Heatran|153/386 par -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|177/386 par|[from] item: Leftovers -|turn|664 -|c|★Crime♥|lol -|choice|switch 6|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|305/363 -|cant|p2a: Heatran|par -| -|-heal|p1a: U Jelly Bruh?|327/363|[from] item: Black Sludge -|-heal|p2a: Heatran|201/386 par|[from] item: Leftovers -|turn|665 -|choice|move 4|switch 4 -| -|switch|p2a: Cobalion|Cobalion|386/386 slp -|-damage|p2a: Cobalion|374/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|371/386 slp -| -|-heal|p1a: U Jelly Bruh?|349/363|[from] item: Black Sludge -|turn|666 -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|368/386 slp -|cant|p2a: Cobalion|slp -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|turn|667 -|c|★Crime♥|those turns -|c|★Crime♥|incredible -|choice|switch 2|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|380/394 tox -|-damage|p2a: Slowbro|331/394 tox|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-damage|p2a: Slowbro|307/394 tox|[from] psn -|turn|668 -|c|★Crime♥|might smoke outside of my window -|c|★Crime♥|lol -|choice|move 4|switch 5 -| -|switch|p2a: Cobalion|Cobalion|368/386 slp -|-damage|p2a: Cobalion|356/386 slp|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Cobalion -|-fail|p2a: Cobalion -| -|turn|669 -|c|★CHEF BOY4RDEEZNUTS|whens the last time you attacked -|choice|move 3|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|255/394 tox -|choice|switch 2| -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|-damage|p2a: Slowbro|231/394 tox|[from] psn -|turn|670 -|c|★Crime♥|the toxic doesnt matter that much on my slowbro -|choice|move 4|switch 5 -| -|switch|p2a: Cobalion|Cobalion|356/386 slp -|-damage|p2a: Cobalion|344/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|341/386 slp -| -|turn|671 -|c|★Crime♥|we are the best stallers out there -|c|★Crime♥|:) -|choice|switch 5|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|362/394 tox -|-damage|p2a: Slowbro|313/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|308/352 tox -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|289/394 tox|[from] psn -|turn|672 -|choice|switch 5|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Cobalion|Cobalion|341/386 slp -|-damage|p2a: Cobalion|329/386 slp|[from] Stealth Rock -| -|turn|673 -|c|★CHEF BOY4RDEEZNUTS|if we both stopped switching it would go faster -|choice|move 3|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-crit|p2a: Slowbro -|-damage|p2a: Slowbro|271/394 tox -| -|-damage|p2a: Slowbro|247/394 tox|[from] psn -|turn|674 -|c|★Crime♥|but we have to switch -|c|★CHEF BOY4RDEEZNUTS|you have scalds -|c|★Crime♥|its a part of the stall -|c|★Crime♥|ohh i rather safe them -|c|★Crime♥|for later -|c|★Crime♥|dont have many left -|c|★Crime♥|XD -|c|★CHEF BOY4RDEEZNUTS|how much later jesus christ -|choice|switch 3|switch 5 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Cobalion|Cobalion|329/386 slp -|-damage|p2a: Cobalion|317/386 slp|[from] Stealth Rock -| -|turn|675 -|c|★Crime♥|lol -|c| lollity|its still fucking going -|c|★Crime♥|the game didnt even start yet -|c| lollity|it sbeen over an hour -|c|★CHEF BOY4RDEEZNUTS|i want to go to bed so bad -|choice|switch 2|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|378/394 tox -|-damage|p2a: Slowbro|329/394 tox|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-damage|p2a: Slowbro|305/394 tox|[from] psn -|turn|676 -|c|★Crime♥|lol -|c|★CHEF BOY4RDEEZNUTS|pls attack me -|choice|move 1|switch 5 -| -|switch|p2a: Cobalion|Cobalion|317/386 slp -|-damage|p2a: Cobalion|305/386 slp|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|270/386 slp -| -|turn|677 -|c|★Crime♥|no -|c|★Crime♥|you have heal bells -|c|★CHEF BOY4RDEEZNUTS|i have a heal bell -|choice|move 3|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|201/386 par -|-damage|p2a: Heatran|153/386 par|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|U-turn|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|139/386 par -|c|★CHEF BOY4RDEEZNUTS|im switching but im at least still using some of my pp -|choice|switch 3| -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|-heal|p2a: Heatran|163/386 par|[from] item: Leftovers -|turn|678 -|choice|move 3|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|301/394 tox -| -|-damage|p2a: Slowbro|277/394 tox|[from] psn -|turn|679 -|choice|move 4|switch 4 -| -|switch|p2a: Cobalion|Cobalion|270/386 slp -|-damage|p2a: Cobalion|258/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|255/386 slp -| -|turn|680 -|c|★Crime♥|0% -|c|★Crime♥|dmg -|c|★Crime♥|xD -|choice|switch 5|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|681 -|c|★CHEF BOY4RDEEZNUTS|scald me -|c|★CHEF BOY4RDEEZNUTS|do it -|choice|switch 2|move 1 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Slowbro|Scald|p1a: Fatty -|-damage|p1a: Fatty|593/642 -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|682 -|c|★CHEF BOY4RDEEZNUTS|yay lol -|c|★Crime♥|i wont use it -|choice|move 2|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|163/386 par -|-damage|p2a: Heatran|115/386 par|[from] Stealth Rock -|move|p1a: Fatty|Toxic|p2a: Heatran -|-fail|p2a: Heatran -| -|-heal|p2a: Heatran|139/386 par|[from] item: Leftovers -|turn|683 -|c|★CHEF BOY4RDEEZNUTS|god i hate those lefties -|c|★Crime♥|haha -|choice|switch 5|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Stealth Rock|p1a: U Jelly Bruh? -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|163/386 par|[from] item: Leftovers -|turn|684 -|choice|move 4|switch 4 -| -|switch|p2a: Cobalion|Cobalion|255/386 slp -|-damage|p2a: Cobalion|243/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|240/386 slp -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|turn|685 -|choice|switch 2|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: Redbull|Clefable, M|393/393 -| -|turn|686 -|choice|move 2|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|163/386 par -|-damage|p2a: Heatran|115/386 par|[from] Stealth Rock -|move|p1a: Redbull|Flamethrower|p2a: Heatran -|-start|p2a: Heatran|ability: Flash Fire -| -|-heal|p2a: Heatran|139/386 par|[from] item: Leftovers -|turn|687 -|choice|switch 2|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Stealth Rock|p1a: U Jelly Bruh? -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|163/386 par|[from] item: Leftovers -|turn|688 -|choice|move 3|switch 5 -| -|-end|p2a: Heatran|ability: Flash Fire|[silent] -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|299/394 tox -| -|-damage|p2a: Slowbro|275/394 tox|[from] psn -|turn|689 -|choice|move 4|switch 4 -| -|switch|p2a: Cobalion|Cobalion|240/386 -|-damage|p2a: Cobalion|228/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|225/386 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|turn|690 -|c|★CHEF BOY4RDEEZNUTS|attack me -|c|★Crime♥|no ty -|c|★Crime♥|im going to have a smoke -|c|★Crime♥|what about that -|c|★Crime♥|dont i deserve one? -|c|★Crime♥|lol -|c|★Crime♥|oh my god -|c|★Crime♥|4 hours battling -|c|★Crime♥|10 more turns -|c|★CHEF BOY4RDEEZNUTS|i wanna go to bed -|c|★Crime♥|!! -|choice|switch 4|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Roar|p1a: Annoying AF -|drag|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|turn|691 -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|301/394 tox -| -|-damage|p2a: Slowbro|277/394 tox|[from] psn -|turn|692 -|c|★CHEF BOY4RDEEZNUTS|i need goth back -|choice|switch 3|switch 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Cobalion|Cobalion|225/386 -|-damage|p2a: Cobalion|213/386|[from] Stealth Rock -| -|turn|693 -|c|★Crime♥|goth? -|c|★CHEF BOY4RDEEZNUTS|gothitelle -|c|★CHEF BOY4RDEEZNUTS|shadow tag -|c|★CHEF BOY4RDEEZNUTS|stops switches -|c|★Crime♥|lol -|choice|move 4|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|163/386 par -|-damage|p2a: Heatran|115/386 par|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Heatran -|-fail|p2a: Heatran -| -|-heal|p2a: Heatran|139/386 par|[from] item: Leftovers -|turn|694 -|c|★Crime♥|that pokemon counters me yes -|c|★Crime♥|hope i get a par -|c|★Crime♥|lol -|choice|move 1|move 1 -| -|move|p1a: TheMoreYouKnow|Iron Head|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|115/386 par -|cant|p2a: Heatran|flinch -| -|-heal|p2a: Heatran|139/386 par|[from] item: Leftovers -|turn|695 -|choice|switch 3|move 1 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Lava Plume|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|327/363 -| -|-heal|p1a: U Jelly Bruh?|349/363|[from] item: Black Sludge -|-heal|p2a: Heatran|163/386 par|[from] item: Leftovers -|turn|696 -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|301/394 tox -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|277/394 tox|[from] psn -|turn|697 -|choice|switch 2|switch 5 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|switch|p2a: Cobalion|Cobalion|213/386 -|-damage|p2a: Cobalion|201/386|[from] Stealth Rock -| -|turn|698 -|choice|move 3|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|163/386 par -|-damage|p2a: Heatran|115/386 par|[from] Stealth Rock -|move|p1a: Redbull|Wish|p1a: Redbull -| -|-heal|p2a: Heatran|139/386 par|[from] item: Leftovers -|turn|699 -|c|★Crime♥|omg -|c|★Crime♥|1 more turn -|c|★Crime♥|700!!!! -|c|★Crime♥|OMG -|choice|switch 5|move 3 -| -|switch|p1a: Fatty|Chansey, F|593/642 -|cant|p2a: Heatran|par -| -|-heal|p1a: Fatty|642/642|[from] move: Wish|[wisher] Redbull -|-heal|p2a: Heatran|163/386 par|[from] item: Leftovers -|turn|700 -|choice|switch 2|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Stealth Rock|p1a: U Jelly Bruh? -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|187/386 par|[from] item: Leftovers -|turn|701 -|choice|move 4|switch 4 -| -|switch|p2a: Cobalion|Cobalion|201/386 -|-damage|p2a: Cobalion|189/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|186/386 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|turn|702 -|c|★CHEF BOY4RDEEZNUTS|whos still alive in here -|c|★Crime♥|not me -|c| LifeisDANK|JESUS -|c|★Crime♥|why timer :'( -|c|★Crime♥|after 4 hours -|c|★CHEF BOY4RDEEZNUTS|yeah 4 hours i wanna sleep -|c| lollity|im here -|c| lollity|mannn -|choice|move 3|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|293/394 tox -| -|-damage|p2a: Slowbro|269/394 tox|[from] psn -|turn|703 -|c|★CHEF BOY4RDEEZNUTS|ive lost my patience -|c| lollity|y'all -|c|★Crime♥|pls put the timer off -|c|★Crime♥|i wanna smoke -|c| lollity|better hurry up -|choice|move 4|switch 5 -| -|switch|p2a: Cobalion|Cobalion|186/386 -|-damage|p2a: Cobalion|174/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|171/386 -| -|turn|704 -|c| lollity|700 turns jesus -|c|★Crime♥|lol -|c| LifeisDANK|i cant see what is happening HOW DID YOU GET 700 turns -|c| lollity|throug stall -|c| lollity|and all 12 pokemon are stll alive -|choice|switch 4|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|705 -|choice|switch 3|switch 5 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Cobalion|Cobalion|171/386 -|-damage|p2a: Cobalion|159/386|[from] Stealth Rock -| -|turn|706 -|c|★CHEF BOY4RDEEZNUTS|attack me pussy -|choice|switch 6|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|707 -|c|★Crime♥|lol -|choice|move 3|move 1 -| -|move|p2a: Slowbro|Scald|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|214/301 -|-status|p1a: I <3 Stall|brn -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|-damage|p1a: I <3 Stall|177/301 brn|[from] brn -|turn|708 -|c|★Crime♥|when i have to yes.. -|c|★Crime♥|the right moments -|choice|switch 2|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|187/386 par -|-damage|p2a: Heatran|139/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|642/642 -| -|-heal|p2a: Heatran|163/386 par|[from] item: Leftovers -|turn|709 -|c|★CHEF BOY4RDEEZNUTS|you had a million right moments -|choice|switch 4|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Taunt|p1a: U Jelly Bruh? -|-start|p1a: U Jelly Bruh?|move: Taunt -| -|-heal|p2a: Heatran|187/386 par|[from] item: Leftovers -|turn|710 -|c| LifeisDANK|how did this come to this -|c| Gaussfield|well -|c| Gaussfield|this should take a while huh -|c|★CHEF BOY4RDEEZNUTS|i basically cant attack -|c| LifeisDANK|oh lordy -|c|★Crime♥|you cant attack -|c|★Crime♥|bceause i out pp'd you -|c|★CHEF BOY4RDEEZNUTS|because youre a switch stally mother lover -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|295/394 tox -| -|-damage|p2a: Slowbro|271/394 tox|[from] psn -|turn|711 -|c|★Crime♥|i didnt switch stall -|c|★Crime♥|after 600+ i used to switch more -|c|★Crime♥|be honest -|c|★Crime♥|lol -|c| Gaussfield|does that slowbro have rgen? -|c| Gaussfield|regen* -|c| Amber Torrey|yes -|c|★Crime♥|yees -|c| Gaussfield|oh my god -|c| Gaussfield|this is amazing -|choice|switch 3|switch 5 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|switch|p2a: Cobalion|Cobalion|159/386 -|-damage|p2a: Cobalion|147/386|[from] Stealth Rock -| -|turn|712 -|c| Amber Torrey|which makes him the ultimate switch staller -|c|★Crime♥|yes -|c|★Crime♥|slowbro wins -|c|★Crime♥|lol -|choice|switch 3|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|713 -|choice|move 3|move 3 -| -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Slowbro -|-supereffective|p2a: Slowbro -|-damage|p2a: Slowbro|275/394 tox -|move|p2a: Slowbro|Toxic|p1a: U Jelly Bruh? -|-immune|p1a: U Jelly Bruh?|[msg] -| -|-damage|p2a: Slowbro|227/394 tox|[from] psn -|turn|714 -|c| LifeisDANK|ill watch this untill im tired i guess -|choice|move 2|switch 5 -| -|switch|p2a: Cobalion|Cobalion|147/386 -|-damage|p2a: Cobalion|135/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Cobalion -|-immune|p2a: Cobalion|[msg] -| -|turn|715 -|c| Gaussfield|i m m u n e -|c| Amber Torrey|i'm about to stop watching to much switch stalling not enough skill -|c|★Crime♥|not enough skill? -|c|★Crime♥|we are out of pp -|c|★Crime♥|lol -|c|★CHEF BOY4RDEEZNUTS|no u are not -|c|★Crime♥|ofcourse we have to switch -|c| Amber Torrey|not my problem -|c|★CHEF BOY4RDEEZNUTS|you have like 6 scalds -|c| LifeisDANK|,':) -|choice|move 2|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|358/394 tox -|-damage|p2a: Slowbro|309/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Acid Spray|p2a: Slowbro -|-damage|p2a: Slowbro|261/394 tox -|-unboost|p2a: Slowbro|spd|2 -| -|-damage|p2a: Slowbro|237/394 tox|[from] psn -|turn|716 -|c|★Crime♥|like 6 scalds '' -|c|★CHEF BOY4RDEEZNUTS|4 -|choice|move 3|switch 5 -| -|switch|p2a: Cobalion|Cobalion|135/386 -|-damage|p2a: Cobalion|123/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|112/386 -|-ability|p2a: Cobalion|Justified|boost -|-boost|p2a: Cobalion|atk|1 -| -|turn|717 -|c|★Crime♥|4'' -|c| Gaussfield|dat attack boost -|c| LifeisDANK|gg -|choice|switch 3|move 3 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Cobalion|Rest|p2a: Cobalion -|-status|p2a: Cobalion|slp -|-heal|p2a: Cobalion|386/386 slp|[silent] -|-status|p2a: Cobalion|slp|[from] move: Rest -| -|turn|718 -|c| LifeisDANK|jk -|c| Amber Torrey|this is kinda why they shouldn't give every pokemon move a pp max... -|c| Gaussfield|REST -|c|★Crime♥|rest op -|c| Gaussfield|geezus -|c|★CHEF BOY4RDEEZNUTS|if he would attack he could take advantage of it -|c|★Crime♥|she* -|c|★Crime♥|lel -|c|★Crime♥|can we get to turn 800 -|c|★Crime♥|pls -|c| LifeisDANK|this is insane -|c|★Crime♥|im so excited -|c|★Crime♥|lol -|c| Amber Torrey|Kinda a love how it no longer is counting your guys turns -|choice|switch 5|move 2 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|cant|p2a: Cobalion|slp -| -|turn|719 -|choice|move 4|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|187/386 par -|-damage|p2a: Heatran|139/386 par|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|163/386 par|[from] item: Leftovers -|turn|720 -|c| LifeisDANK|the highest turns i ever got was around 150 on a tanky struggle battle -|c| Gaussfield|is this it -|c| Gaussfield|is this the redbull sweep -|choice|move 4|move 2 -| -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -|move|p2a: Heatran|Roar|p1a: Redbull -|drag|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-heal|p2a: Heatran|187/386 par|[from] item: Leftovers -|turn|721 -|c| LifeisDANK|kets see -|c| LifeisDANK|naw -|c| Gaussfield|nope -|choice|switch 4|move 3 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Heatran|Stealth Rock|p1a: Fatty -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|211/386 par|[from] item: Leftovers -|turn|722 -|choice|switch 5|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|-damage|p1a: Annoying AF|308/352 tox|[from] Stealth Rock -|move|p2a: Heatran|Taunt|p1a: Annoying AF -|-start|p1a: Annoying AF|move: Taunt -| -|-heal|p2a: Heatran|235/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|723 -|c|★Crime♥|we are battling over 5 hours -|c|★Crime♥|lol -|c|★Crime♥|my eyessssssss -|c| LifeisDANK|5 HOURS -|c| Gaussfield|dude -|c|★CHEF BOY4RDEEZNUTS|I WANNA GO TO BED JESUS CHRIST -|c|★Crime♥|lol -|c| LifeisDANK|its 4am here -|c| LifeisDANK|how late is it there -|c| Gaussfield|i don't know if i should be impressed or concerned -|choice|move 1|move 4 -| -|-activate|p1a: Annoying AF|move: Struggle -|move|p1a: Annoying AF|Struggle|p2a: Heatran -|-damage|p2a: Heatran|202/386 par -|-damage|p1a: Annoying AF|264/352 tox|[from] recoil -|move|p2a: Heatran|Taunt|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p2a: Heatran|226/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|308/352 tox|[from] ability: Poison Heal -|turn|724 -|c|★CHEF BOY4RDEEZNUTS|u should be concerned -|choice|move 1|move 1 -| -|-activate|p1a: Annoying AF|move: Struggle -|move|p1a: Annoying AF|Struggle|p2a: Heatran -|-damage|p2a: Heatran|192/386 par -|-damage|p1a: Annoying AF|220/352 tox|[from] recoil -|move|p2a: Heatran|Lava Plume|p1a: Annoying AF -|-damage|p1a: Annoying AF|61/352 tox -| -|-heal|p2a: Heatran|216/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|105/352 tox|[from] ability: Poison Heal -|-end|p1a: Annoying AF|move: Taunt -|turn|725 -|c|★CHEF BOY4RDEEZNUTS|now he attacks... -|c| LifeisDANK|first kill?! -|choice|move 3|move 4 -| -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|17/352 tox -|move|p2a: Heatran|Taunt|p1a: Annoying AF -|-start|p1a: Annoying AF|move: Taunt -| -|-heal|p2a: Heatran|240/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|61/352 tox|[from] ability: Poison Heal -|turn|726 -|choice|switch 3|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -|switch|p2a: Slowbro|Slowbro, F|368/394 tox -|-damage|p2a: Slowbro|319/394 tox|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|340/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|295/394 tox|[from] psn -|turn|727 -|c|★CHEF BOY4RDEEZNUTS|he could kill something if he attacked... -|c| Amber Torrey|I still think poison heal, heals for way to much -|choice|move 4|switch 4 -| -|switch|p2a: Cobalion|Cobalion|386/386 slp -|-damage|p2a: Cobalion|374/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|371/386 slp -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|362/363|[from] item: Black Sludge -|turn|728 -|c|★Crime♥|turn 800 -|c| Gaussfield|i think it heals for just right -|c|★Crime♥|here we go -|c|★Crime♥|<3 -|choice|switch 3|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|61/352 tox -|cant|p2a: Cobalion|slp -| -|-heal|p1a: Annoying AF|105/352 tox|[from] ability: Poison Heal -|turn|729 -|c| Amber Torrey|1/8th is way to much hp each turn -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|17/352 tox -| -|-heal|p1a: Annoying AF|61/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|730 -|c| LifeisDANK|its annoying tbh -|c| Gaussfield|you either have breloom, who doesn't quite have coverage -|c| Gaussfield|or gliscor, which is hard to get in the first place -|c| tuxedo_cat|No one's died yet? -|c|★CHEF BOY4RDEEZNUTS|its annoying when your opp refuses to use his pp -|choice|move 4|move 3 -| -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-singleturn|p1a: Annoying AF|Protect -|move|p2a: Slowbro|Toxic|p1a: Annoying AF -|-activate|p1a: Annoying AF|Protect -| -|-heal|p1a: Annoying AF|105/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|731 -|choice|move 3|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|240/386 par -|-damage|p2a: Heatran|192/386 par|[from] Stealth Rock -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-fail|p1a: Annoying AF|move: Substitute -| -|-heal|p2a: Heatran|216/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|149/352 tox|[from] ability: Poison Heal -|turn|732 -|c| LifeisDANK|if only you had eq still -|c|★Crime♥|only'' -|c| Amber Torrey|wouldn't matter -|c| Amber Torrey|would switch to skarmory -|c|★Crime♥|XD -|c|★CHEF BOY4RDEEZNUTS|hed switch to skarm every time -|c|★Crime♥|or cobalionnnnnnn -|c|★Crime♥|cobalion op -|c| Gaussfield|there's like 1 place in all of gen vi where you can get immunity gligar -|c|★Crime♥|!data cobalion -|c|~|/data-pokemon Cobalion - -|c| Gaussfield|and sometimes it rains -|c| Gaussfield|so you can't use honey -|c| Gaussfield|or sweet scent -|choice|switch 5|move 3 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Heatran|Stealth Rock|p1a: Fatty -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|240/386 par|[from] item: Leftovers -|turn|733 -|c|★Crime♥|use ur last heal bell -|choice|switch 3|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|362/363 -|-damage|p1a: U Jelly Bruh?|317/363|[from] Stealth Rock -|move|p2a: Heatran|Taunt|p1a: U Jelly Bruh? -|-start|p1a: U Jelly Bruh?|move: Taunt -| -|-heal|p1a: U Jelly Bruh?|339/363|[from] item: Black Sludge -|-heal|p2a: Heatran|264/386 par|[from] item: Leftovers -|turn|734 -|c|★Crime♥|and ill start attacking -|c| LifeisDANK|lel -|c|★Crime♥|im gonna stay with heatran -|c| LifeisDANK|negotiating moves -|c|★Crime♥|knock off me -|c|★Crime♥|ur last one -|c|★Crime♥|and you win the game -|c|★Crime♥|if not -|c|★Crime♥|you lose -|c|★CHEF BOY4RDEEZNUTS|eat my ass -|choice|move 4|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|338/394 tox -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|361/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|314/394 tox|[from] psn -|turn|735 -|c|★Crime♥|lol -|c|★Crime♥|you were so gentle to me 6 hours ago.. -|c|★Crime♥|now you are so rude to me -|c|★Crime♥|when we first met.. -|c|★Crime♥|well i understand -|c| LifeisDANK|Thats how a relationship goes m8 -|c|★Crime♥|this game is very exhausting -|choice|move 3|switch 4 -| -|switch|p2a: Cobalion|Cobalion|371/386 slp -|-damage|p2a: Cobalion|359/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Knock Off|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|348/386 slp -|-ability|p2a: Cobalion|Justified|boost -|-boost|p2a: Cobalion|atk|1 -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|-end|p1a: U Jelly Bruh?|move: Taunt -|turn|736 -|c| Gaussfield|saturday was like 2 days ago -|c|★CHEF BOY4RDEEZNUTS|im cranky when i want sleepppppp -|c| BayFence|6 hours ? -|c|★Crime♥|there we go -|c| Gaussfield|now is not the time for eating ass -|c| LifeisDANK|welcome to hell -|c|★Crime♥|last knock off -|c|★Crime♥|rip -|c| Amber Torrey|iron heads gonna wreck ya up if he has pp still -|choice|switch 5|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|264/386 par -|-damage|p2a: Heatran|216/386 par|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|149/352 tox -| -|-heal|p2a: Heatran|240/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|193/352 tox|[from] ability: Poison Heal -|turn|737 -|choice|switch 5|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Stealth Rock|p1a: U Jelly Bruh? -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|264/386 par|[from] item: Leftovers -|turn|738 -|c| LifeisDANK|I just have to see how this ends -|choice|move 4|switch 5 -| -|switch|p2a: Cobalion|Cobalion|348/386 slp -|-damage|p2a: Cobalion|336/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|333/386 slp -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|turn|739 -|c| Crean|how is this still 6v6 -|c| Crean|smh -|c| EL20|http://play.pokemonshowdown.com/battle-ou-305002749 -|choice|switch 5|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|193/352 tox -| -|-heal|p1a: Annoying AF|237/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|740 -|c| EL20|lol fail -|c| Amber Torrey|sigh rapid spin has way to much pp... -|choice|move 4|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|264/386 par -|-damage|p2a: Heatran|216/386 par|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p2a: Heatran|240/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|281/352 tox|[from] ability: Poison Heal -|turn|741 -|choice|switch 5|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|264/386 par|[from] item: Leftovers -|turn|742 -|choice|move 4|move 3 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|259/386 par -|move|p2a: Heatran|Stealth Rock|p1a: U Jelly Bruh? -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|283/386 par|[from] item: Leftovers -|turn|743 -|c| Crean|i legit took like 6minutes to refresh -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|279/386 par -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|303/386 par|[from] item: Leftovers -|turn|744 -|c| LifeisDANK|stealth rock also has a lot of pp -|c| EL20|1000+? -|choice|switch 5|move 4 -| -|switch|p1a: Annoying AF|Gliscor, M|281/352 tox -|move|p2a: Heatran|Taunt|p1a: Annoying AF -|-start|p1a: Annoying AF|move: Taunt -| -|-heal|p2a: Heatran|327/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|325/352 tox|[from] ability: Poison Heal -|turn|745 -|c| Crean|that battle made my computer freeze -|c|★Crime♥|lol -|choice|move 1|move 3 -| -|-activate|p1a: Annoying AF|move: Struggle -|move|p1a: Annoying AF|Struggle|p2a: Heatran -|-damage|p2a: Heatran|293/386 par -|-damage|p1a: Annoying AF|237/352 tox|[from] recoil -|move|p2a: Heatran|Stealth Rock|p1a: Annoying AF -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|317/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|281/352 tox|[from] ability: Poison Heal -|turn|746 -|c| EL20|are y'all doing this on purpose? -|c|&xfix|Okay, the battle finally did load for me. -|c| LifeisDANK|the struggle is real -|c|★CHEF BOY4RDEEZNUTS|no -|c|&xfix|Do you want a tie? -|c| Amber Torrey|welp in the time this battle started -|c|★Crime♥|no please -|c|★Crime♥|im winning -|c|★CHEF BOY4RDEEZNUTS|yes pls -|c|★Crime♥|no -|c| EL20|no tie please, it will be a humiliation -|c| LifeisDANK|FIght -|c| Amber Torrey|found my 6 pokemon breed them iv'ed them ev'ed them and got them to lvl 50 -|c|★CHEF BOY4RDEEZNUTS|youre switch stalling -|c|&xfix|Hm, fair... -|c|★Crime♥|its still a fair legit battle -|c| BayFence|chef lost since he used his last knock off :/ -|c|★Crime♥|:) -|c| Amber Torrey|and this battle isn't over -|c| LifeisDANK|someone needs to get dunked on -|c|★Crime♥|thank you though admin! -|choice|switch 5|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -|move|p2a: Heatran|Taunt|p1a: U Jelly Bruh? -|-start|p1a: U Jelly Bruh?|move: Taunt -| -|-heal|p1a: U Jelly Bruh?|340/363|[from] item: Black Sludge -|-heal|p2a: Heatran|341/386 par|[from] item: Leftovers -|turn|747 -|c|★Crime♥|the game will end soon -|c|★Crime♥|finally.. -|c| EL20|'soon' -|c|★Crime♥|after 6 hours -|c| EL20|someone place this on youtube -|c|&xfix|That was 6 hours? -|c|★Crime♥|yes -|c|★Crime♥|5-6 hours. -|c|★CHEF BOY4RDEEZNUTS|not 6 hours idk how long -|c| Amber Torrey|Wanna hear my amazing IRL competitive team? -|c|★Crime♥|without time stalling -|c| BayFence|na this battle is not 6 hours -|c|★Crime♥|we played 5-6 hours -|c|★Crime♥|it is -|c|★Crime♥|ask CHEF. -|c| BayFence|na -|c|&xfix|By the way, feel free to download a replay after this battle finishes, if you want it. -|c|★CHEF BOY4RDEEZNUTS|at least im still using my pp -|c| LifeisDANK|I accidently refreshed -|c| LifeisDANK|send help -|c| BayFence|one of my friend battle 500 rounds and was like 45 minutes -|c|&xfix|Replay server doesn't handle such long replays last time I checked. -|c|+SpaceBass|Holy shit -|c| EL20|sigh, just play -|choice|move 4|move 2 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|336/386 par -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: I <3 Stall|Sableye-Mega, M|177/301 brn -| -|-heal|p2a: Heatran|360/386 par|[from] item: Leftovers -|-damage|p1a: I <3 Stall|140/301 brn|[from] brn -|turn|748 -|c| EL20|♥ > <3 -|choice|move 4|move 1 -| -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|291/301 brn -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|384/386 par|[from] item: Leftovers -|-damage|p1a: I <3 Stall|254/301 brn|[from] brn -|turn|749 -|c| Amber Torrey|Pidgeot, Jynx, Sawk, Darmanitan, Arbok, Simipour -|choice|switch 3|switch 5 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|750 -|c| Amber Torrey|best team -|choice|move 4|switch 4 -| -|switch|p2a: Cobalion|Cobalion|333/386 slp -|-damage|p2a: Cobalion|321/386 slp|[from] Stealth Rock -|move|p1a: Fatty|Heal Bell|p1a: Fatty -|-cureteam|p1a: Fatty|[from] move: HealBell -| -|turn|751 -|c| AtmaARMS|took me a while but i finally got it loaded -|c| EL20|he -|choice|switch 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|254/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|752 -|c| LifeisDANK|This is the most determined battle ive ever seen. i dont even have 5 hours straight to spare in a day -|c|★CHEF BOY4RDEEZNUTS|BECAUSE ITS NOTHING BUT SWITCHING -|c|★CHEF BOY4RDEEZNUTS|sigh..... -|choice|switch 2|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|340/363 -|move|p2a: Slowbro|Toxic|p1a: U Jelly Bruh? -|-immune|p1a: U Jelly Bruh?|[msg] -| -|-heal|p1a: U Jelly Bruh?|362/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|753 -|c| Gaussfield|switching needs pp :V -|choice|move 4|switch 4 -| -|switch|p2a: Cobalion|Cobalion|321/386 slp -|-damage|p2a: Cobalion|309/386 slp|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|306/386 slp -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|turn|754 -|c| EL20|worst idea ever -|choice|switch 2|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|254/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|755 -|c| LifeisDANK|that would be odd -|c| LifeisDANK|like the pokeball broke -|c| EL20|:D -|c| iliketrains11|FUNBRO IS BACK -|c|★CHEF BOY4RDEEZNUTS|not fun if you ask me -|c| EL20|say hello to youtube -|c| LifeisDANK|Eyyyy -|c|★Crime♥|hi youtube im the best staller -|c|★Crime♥|just kidding -|c| BayFence|lol best staller? -|c|★CHEF BOY4RDEEZNUTS|cough switch staller cough -|c|★Crime♥|KIDDINGG. -|c| EL20|best? you're not winning -|c|★Crime♥|im bad -|c| LifeisDANK|Hi Youtube Welcome to Hell -|c|★CHEF BOY4RDEEZNUTS|thank you el20 -|choice|switch 3|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|384/386 par -|-damage|p2a: Heatran|336/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|642/642 -| -|-heal|p2a: Heatran|360/386 par|[from] item: Leftovers -|turn|756 -|c| tuxedo_cat|Could it be possible for the match to end as a draw? -|c| BayFence|no -|c| EL20|yes -|c| LifeisDANK|this must end -|c|★CHEF BOY4RDEEZNUTS|staff could end it though right -|c| LifeisDANK|in a conclusion -|c| Amber Torrey|Only if this was tournament rules -|c| BayFence|this battle is for crime -|choice|switch 3|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|254/301 -|move|p2a: Heatran|Taunt|p1a: I <3 Stall -|move|p1a: I <3 Stall|Taunt|p2a: Heatran|[from]Magic Bounce -|-start|p2a: Heatran|move: Taunt -| -|-heal|p2a: Heatran|384/386 par|[from] item: Leftovers -|turn|757 -|c|★Crime♥|yes its for me! -|c| Amber Torrey|where after 75 turns both teams auto lose -|c| EL20|nope -|c| Gaussfield|this battle is a crime -|c| BayFence|chef cannot win withouth that knock off he used :c -|c| LifeisDANK|thats a little short -|c| tuxedo_cat|We're 10 fold past that mark. -|c| EL20|new worst idea ever, amber -|choice|switch 3|switch 4 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Cobalion|Cobalion|306/386 slp -|-damage|p2a: Cobalion|294/386 slp|[from] Stealth Rock -| -|turn|758 -|c|★Crime♥|only 3% dmg from rocks -|c|★Crime♥|lol -|c| Amber Torrey|Sorry but it's not an idea -|c|★CHEF BOY4RDEEZNUTS|attack me pussy -|c|★Crime♥|omg turn 800 soon! -|c| Amber Torrey|it already exists -|c|★Crime♥|go to sleep CHEF -|c|★CHEF BOY4RDEEZNUTS|at least you can still attack -|c| EL20|showdown's server gonna melt after this -|c| BayFence|i want to battle with u crime :3 -|c| Gaussfield|"soon" -|c|★Crime♥|i cant attack -|c|★Crime♥|i have 3 scald left -|c|★CHEF BOY4RDEEZNUTS|yes you can -|c| Amber Torrey|matches don't need to last more then 75 rounds -|choice|switch 5|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|281/352 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|-status|p1a: Annoying AF|tox|[from] item: Toxic Orb -|turn|759 -|c| EL20|stupid ^ -|c| LifeisDANK|im waiting for the struggle battle of the century -|c| Gaussfield|but here we are -|c| Gaussfield|at more than 750 rounds -|c| Amber Torrey|it's purposeful switch stalling at that point -|c|★Crime♥|at the late yes Amber -|c| EL20|protect sub FYW -|c| EL20|FTW -|choice|switch 5|switch 5 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Cobalion|Cobalion|294/386 slp -|-damage|p2a: Cobalion|282/386 slp|[from] Stealth Rock -| -|turn|760 -|c| tuxedo_cat|How about this. No more switching is allowed. -|c| EL20|this ^ -|c|★CHEF BOY4RDEEZNUTS|yes pls -|c| LifeisDANK|thats lame -|c| tuxedo_cat|You stick with what you've got. -|choice|switch 5|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|281/352 tox -| -|-heal|p1a: Annoying AF|325/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|761 -|c|★Crime♥|that would be unfair cause, we have different teams -|c| EL20|both failed -|c|★CHEF BOY4RDEEZNUTS|no regen then hehe -|c| LifeisDANK|throw those pokes on the rocks till they cant feel their feet -|choice|move 3|move 1 -| -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|237/352 tox -|move|p2a: Slowbro|Scald|p1a: Annoying AF -|-supereffective|p1a: Annoying AF -|-end|p1a: Annoying AF|Substitute -| -|-heal|p1a: Annoying AF|281/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|762 -|c| iliketrains11|what i dont get is -|c| iliketrains11|why hasnt any1 forfeited yet -|c| iliketrains11|and how does every1 still have so much pp -|c| LifeisDANK|DETERMINATION -|c|★CHEF BOY4RDEEZNUTS|pride -|c| EL20|why would any do so? -|c|★Crime♥|i used scald -|c|★Crime♥|happy? -|c|★CHEF BOY4RDEEZNUTS|i want staff to end this shit -|c| LifeisDANK|or did you ,':) -|c| EL20|if you are a loser, don't impose this on others, lol -|choice|move 4|switch 5 -| -|switch|p2a: Cobalion|Cobalion|282/386 slp -|-damage|p2a: Cobalion|270/386 slp|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p1a: Annoying AF|325/352 tox|[from] ability: Poison Heal -|turn|763 -|c|★Crime♥|but i dont want this to end.. -|c|★Crime♥|bceause im winning -|c|★Crime♥|and i worked 6 hours for it -|c|★CHEF BOY4RDEEZNUTS|no youre not youre fucking stupid -|c| EL20|you're winning based on? -|c| LifeisDANK|this is art -|c|★Crime♥|so this game is mine.. -|c|★CHEF BOY4RDEEZNUTS|and it hasnt been 6 hours -|c|★CHEF BOY4RDEEZNUTS|tell him el20 -|c|★Crime♥|well 5 hours then -|choice|switch 6|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Redbull|Clefable, M|393/393 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|764 -|c| BayFence|this battles is less than 5 hours -|c|★Crime♥|nope -|c| LifeisDANK|I'll write a novel on the great 10 year stall war -|c|★Crime♥|its not -|c| EL20|how is this even close to a redbull? -|c| BayFence|yes it is -|c|★Crime♥|no -|c|★Crime♥|its not. -|c|★CHEF BOY4RDEEZNUTS|redbull gives you wings -|c| EL20|LOL -|choice|switch 3|switch 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|254/301 -|switch|p2a: Heatran|Heatran, F, shiny|384/386 par -|-damage|p2a: Heatran|336/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|360/386 par|[from] item: Leftovers -|turn|765 -|c| BayFence|bro i was in a 500 battle before it was 45 minutes -|c| Amber Torrey|Both of you at the start Full stall team if a fun playstyle -|c| Amber Torrey|you both are toxic as hell -|c| Amber Torrey|is* -|c| BayFence|do not exaggerate -|c| EL20|sigh, if you love switching so much, just switch until rocks lapidate all your pokés -|c|★CHEF BOY4RDEEZNUTS|lapidate his pokes ^ -|choice|move 4|move 4 -| -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|384/386 par|[from] item: Leftovers -|turn|766 -|c| tuxedo_cat|Amber, of course they're toxic. -|c| tuxedo_cat|They're stallers. -|c| tuxedo_cat|It's what they use. -|c|★CHEF BOY4RDEEZNUTS|at least im still using my pp -|c|★Crime♥|cat wanna play me after this game? -|c|★Crime♥|same team -|c|★CHEF BOY4RDEEZNUTS|i doubt he wants to play -|c| LifeisDANK|wouldnt the rocks start to just soak into their feet till they are off the field. they've fallen so many times on them.. -|c|★Crime♥|you'd be playing for 8 hours. -|c| tuxedo_cat|...In random battles? -|c| BayFence|lets play with me -|c| BayFence|i am staller too -|c|★Crime♥|my coballion takes 3% dmg rocks -|c|★Crime♥|lol -|choice|move 2|switch 5 -| -|switch|p2a: Cobalion|Cobalion|270/386 slp -|-damage|p2a: Cobalion|258/386 slp|[from] Stealth Rock -|move|p1a: I <3 Stall|Calm Mind|p1a: I <3 Stall -|-boost|p1a: I <3 Stall|spa|1 -|-boost|p1a: I <3 Stall|spd|1 -| -|turn|767 -|c| tuxedo_cat|I lost my legendary bird team. -|c|★CHEF BOY4RDEEZNUTS|fucking attack me pussy ass bitch -|choice|move 3|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|384/386 par -|-damage|p2a: Heatran|336/386 par|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Heatran -|-start|p2a: Heatran|ability: Flash Fire -| -|-heal|p2a: Heatran|360/386 par|[from] item: Leftovers -|turn|768 -|c| EL20|23 more turns until coba is dead then -|c|★Crime♥|lol -|c|★Crime♥|wow ur flaming.. -|c|★Crime♥|you was so gentle before -|c| LifeisDANK|it says that you love stall -|choice|switch 5|move 4 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Heatran|Taunt|p1a: Fatty -|-start|p1a: Fatty|move: Taunt -| -|-heal|p2a: Heatran|384/386 par|[from] item: Leftovers -|turn|769 -|c|★CHEF BOY4RDEEZNUTS|yeah i do -|c| EL20|at least someone take the initiative to kill ONE poké -|c| LifeisDANK|this is your present -|c|★CHEF BOY4RDEEZNUTS|but not switch stalll -|c| tuxedo_cat|You've got him! -|c| tuxedo_cat|Go for it! -|c| tuxedo_cat|Flame on! -|choice|switch 2|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-heal|p2a: Heatran|386/386 par|[from] item: Leftovers -|turn|770 -|c| tuxedo_cat|No! -|c| BayFence|che keep playing i think u can win -|c| BayFence|chef* -|c| qsns|why would you ever waste pp and roar -|c| qsns|stop being bad -|c| EL20|you are bad -|c| Gaussfield|we're all bad deep inside -|c| tuxedo_cat|qsns, they've gone on since before you were born. -|c| EL20|and bald outside -|c|★CHEF BOY4RDEEZNUTS|my only attacks are flamethrower, moonblast, and rapid spin -|c| LifeisDANK|im more than bad ,':) -|choice|switch 6|move 1 -| -|switch|p1a: Annoying AF|Gliscor, M|325/352 tox -|move|p2a: Heatran|Lava Plume|p1a: Annoying AF -|-damage|p1a: Annoying AF|93/352 tox -| -|-heal|p1a: Annoying AF|137/352 tox|[from] ability: Poison Heal -|turn|771 -|c| EL20|YES -|c| EL20|die -|choice|move 4|switch 4 -| -|-end|p2a: Heatran|ability: Flash Fire|[silent] -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p1a: Annoying AF|181/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|772 -|c| tuxedo_cat|Taunt! -|c| tuxedo_cat|Oh come on! -|c|+SpaceBass|This is actually my idea of hell -|c|★CHEF BOY4RDEEZNUTS|pussy -|c| anthonygmars|my dick > all of you -|c|★CHEF BOY4RDEEZNUTS|you could have gotten a kill -|c| LifeisDANK|stop tallkin about cats -|c|★Crime♥|you keep protecting me -|c|★Crime♥|and running me out of moves -|c|★Crime♥|you just want to win this -|c| EL20|anthonygmars, lol the 1v1 eternal loser. please leave -|c| Aranacana|Lets lag boiis -|c| anthonygmars|lol you're funny -|choice|switch 2|switch 4 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Heatran|Heatran, F, shiny|386/386 par -|-damage|p2a: Heatran|338/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|362/386 par|[from] item: Leftovers -|turn|773 -|c| LifeisDANK|thanks m8 -|c| anthonygmars|that's why i raped your ass -|c| LifeisDANK|yum -|c|★CHEF BOY4RDEEZNUTS|yucky -|c| anthonygmars|indeed -|c| EL20|LOL you never beat me -|c| LifeisDANK|thats beastiality -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: Fatty|Wish|p1a: Fatty -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|774 -|c| LifeisDANK|ass raping is cruel to donkeys -|c| anthonygmars|;) -|c| LifeisDANK|;0 -|choice|move 2|move 3 -| -|move|p1a: Fatty|Toxic|p2a: Slowbro -|-fail|p2a: Slowbro|tox -|move|p2a: Slowbro|Toxic|p1a: Fatty -|-status|p1a: Fatty|tox -| -|-damage|p1a: Fatty|602/642 tox|[from] psn -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|775 -|c| Rath111|i thought there was an endless battle clause -|c|★Crime♥|he was so happy he poisoned my slowbro 400 turns ago, look at him now -|c| EL20|it's not endless :3 -|c|★Crime♥|not happy about it anymore .. lol -|c| anthonygmars|EL20: how do i report people talking trash to me. they hurt my feelings because i'm a little bitch -|c| anthonygmars|i'm not the one who gets butthurt over a game -|c| EL20|whatever mate, dont' talk to me :3 -|choice|switch 2|switch 5 -| -|switch|p1a: Annoying AF|Gliscor, M|181/352 tox -|switch|p2a: Cobalion|Cobalion|258/386 slp -|-damage|p2a: Cobalion|246/386 slp|[from] Stealth Rock -| -|-heal|p1a: Annoying AF|225/352 tox|[from] ability: Poison Heal -|turn|776 -|c| LifeisDANK|the SALT in this chat is amazing -|c|★Crime♥|yes -|choice|switch 6|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|362/386 par -|-damage|p2a: Heatran|314/386 par|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-heal|p2a: Heatran|338/386 par|[from] item: Leftovers -|turn|777 -|c| Rath111|why do people have to be douchebags on smogon -|c|★Crime♥|in my own room! -|c| anthonygmars|NaCl at it's finest -|c| Rath111|i don't understand -|c| LifeisDANK|its delicious -|c| Rath111|you'd think in pokemon you'd find less ass holes -|c|~Zarel|Rath111, there is an endless battle clause, but it only comes into effect when neither player has any way to end the game -|c|★Crime♥|777 -|c| LifeisDANK|nah m8 ppl are agressive about their battle monsters -|c|★CHEF BOY4RDEEZNUTS|zarel can you end this please -|c| EL20|no don't -|c|★Crime♥|no please -|c|★Crime♥|im winning. -|c| anthonygmars|my pocket monster is better than yours -|c| LifeisDANK|dont end the fun -|c|~Zarel|any of them could stop doubleswitching whenever they wanted, so Endless Battle Clause doesn't apply -|c| anthonygmars|no don't end it -|c| EL20|unless each player agrees to it, you have no right to ask for zarel to end it -|c|★Crime♥|this game is legit and fair! -|c|★CHEF BOY4RDEEZNUTS|he can still attack i cant basically -|c|★CHEF BOY4RDEEZNUTS|theres a difference -|c|★Crime♥|and i disagree to end it -|c|★Crime♥|thats ur problem CHEF -|c| EL20|so do i -|c| BayFence|bro u can win just keep plating -|c|★Crime♥|this is my set up team. -|c| LifeisDANK|We didnt start the fire -|choice|switch 2|move 2 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|move|p2a: Heatran|Roar|p1a: Fatty -|drag|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|-heal|p2a: Heatran|362/386 par|[from] item: Leftovers -|turn|778 -|choice|switch 4|switch 5 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|779 -|c| EL20|welcome spectators, popcorn? -|c| charizard8888|**THE LONGEST BATTLE EVER** -|c|★Crime♥|lol -|c|★Crime♥|popcorn! -|choice|switch 6|switch 5 -| -|switch|p1a: Annoying AF|Gliscor, M|225/352 tox -|switch|p2a: Heatran|Heatran, F, shiny|362/386 par -|-damage|p2a: Heatran|314/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|338/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|269/352 tox|[from] ability: Poison Heal -|turn|780 -|c| LifeisDANK|no need to add salt for this popcorn plenty around! -|c| Crean|it is tho -|c| anthonygmars|El20 i want to rape your ass again in 1v1 -|c| EL20|lel -|c| EL20|start by raping me first -|choice|switch 6|switch 5 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|781 -|c| charizard8888|Hey it's Zarel -|c| EL20|then we'll talk about again -|c| LifeisDANK|if its consensual it aint rape -|c| anthonygmars|i rape asses, not humans -|c| anthonygmars|that's disgusting -|c| LifeisDANK|^ -|choice|switch 5|switch 5 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Heatran|Heatran, F, shiny|338/386 par -|-damage|p2a: Heatran|290/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|314/386 par|[from] item: Leftovers -|turn|782 -|c| AtmaARMS|what is the current record for longest battle on PS? -|c| charizard8888|Hi Zarel -|c| EL20|my own record is ~200 -|c|★CHEF BOY4RDEEZNUTS|Zarel pls end my misery -|c| Crean|this battle could go up to 1000 tbh -|c| anthonygmars|NO -|c| anthonygmars|make it to 1000 -|choice|switch 5|switch 5 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|783 -|c|~Zarel|CHEF BOY4RDEEZNUTS, the Forfeit button is right there if you'd like to end your misery -|c|@Former Hope|You could always forfeit if you want to end it because you think you can't win. -|c| Rath111|let this battle continue -|c|★Crime♥|1000 rip -|c| EL20|let's agree to end it on 1000 -|c| Rath111|no -|c|~Zarel|if you'd like, I can add the Forfeit button right here so it's easy to click :) -|c|★Crime♥|yes CHEF you could always forfeit -|c|★Crime♥|if you want to sleep -|c|★CHEF BOY4RDEEZNUTS|sigjh -|c| LifeisDANK|Sleep is for the week -|c| EL20|weak? -|c| LifeisDANK|nah -|c| LifeisDANK|week -|c| LifeisDANK|like week days -|c| Rath111|so much for loving stall -|choice|move 2|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|314/386 par -|-damage|p2a: Heatran|266/386 par|[from] Stealth Rock -|move|p1a: Fatty|Toxic|p2a: Heatran|[miss] -|-miss|p1a: Fatty|p2a: Heatran -| -|-heal|p2a: Heatran|290/386 par|[from] item: Leftovers -|turn|784 -|c| Rath111|lol -|c| EL20|go back to school -|c| Nass-T|How is zarel here -|c| anthonygmars|what number are you guys on the ladder anyways? Does a loss even count? LOL -|c|★Crime♥|CHEF is almost out of PP , i got this uys -|c|★Crime♥|guys* -|c| LifeisDANK|ayyy -|c| Orchestrite|they are around 1400s I think -|c|★Crime♥|he is trying to make me out of PP and win this with a little bit hope.. -|c|★CHEF BOY4RDEEZNUTS|i have at least 30 rapid spins bro -|c| charizard8888|DAMN -|c| MyHandSlipped|this is actual cancer -|choice|switch 5|switch 5 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|785 -|c| EL20|let's place our bets on how many turns the match will last. i say 873 -|c| LifeisDANK|that poor slow bros feet -|c| Gaussfield|at this rate -|c| charizard8888|1500 -|c| Rath111|i say 1000 -|c| anthonygmars|43859042385904238520542 -|choice|switch 6|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|290/386 par -|-damage|p2a: Heatran|242/386 par|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|269/352 tox -| -|-heal|p2a: Heatran|266/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|313/352 tox|[from] ability: Poison Heal -|turn|786 -|c| Orchestrite|Hi myhandslipped -|c| charizard8888|^ -|c|+SpaceBass|mfw this is PS' main tier -|c|&xfix|Yeah, I saw stuff like this in BH. -|c|&xfix|But in OU, crazy. -|choice|switch 6|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|290/386 par|[from] item: Leftovers -|turn|787 -|c|+SpaceBass|I've had some 200+ BH battles -|c|~Zarel|this has to be a record or something -|c|+SpaceBass|But this is madness -|c| Rath111|what's BH? -|c|★Crime♥|lol Zarel -|c|@Former Hope|Balanced Hackmons -|c|&xfix|Balanced Hackmons -|c| charizard8888|Balanced Hackmons -|c|★Crime♥|i think so too -|c| LifeisDANK|this must be the record -|c|@Former Hope|HA -|c| The Suicoon|How long has this game gone on for? -|c| Rath111|hackmons? -|c|@Former Hope|Basically any ability/moveset -|c| charizard8888|This match is getting viral -|c|★Crime♥|i wanna have the PS record.. -|c| Rath111|you mean turns or time? -|c| Rath111|because if it is time, I have no answer -|c| The Suicoon|time. -|choice|switch 5|switch 5 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|788 -|c| LifeisDANK|years -|c| The Suicoon|eaux -|c| charizard8888|Everyone is watching it -|c|★Crime♥|haha im famous! -|c|+SpaceBass|How long has this actually been going timewise -|c| Orchestrite|What was the record for longest battle when endless battle was still a thing? -|c| LifeisDANK|Battle of the century dear folks -|c| charizard8888|^ -|choice|switch 2|switch 5 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Heatran|Heatran, F, shiny|290/386 par -|-damage|p2a: Heatran|242/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|266/386 par|[from] item: Leftovers -|turn|789 -|c| anthonygmars|mayweather vs mayweather -|choice|switch 2|move 2 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|move|p2a: Heatran|Roar|p1a: Fatty -|drag|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-heal|p2a: Heatran|290/386 par|[from] item: Leftovers -|turn|790 -|c| anthonygmars|both running around the ring -|c| LifeisDANK|Ill tell generations of this -|c| Gaussfield|battle of the century is right -|c|@Former Hope|If endless battle was still a thing...endless? -|c| LifeisDANK|also nice joke anthony -|c| Gaussfield|i wouldn't be surprised if this lasted until january -|c| AtmaARMS|place your bets, ladies and gentlemen, place your bets! -|c| charizard8888|If i play for these many turns i would get 35 gg(s) -|c|★CHEF BOY4RDEEZNUTS|im leaving at 800 -|choice|switch 4|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|791 -|c| charizard8888|NO -|c|@Former Hope|That would mean no server restart until then so...yeah, that would be suprising -|c| charizard8888|NOONE IS LEAVING -|c| Rath111|DON"T LEAVE -|c| Rath111|I'LL PLAY FOR U -|c| LifeisDANK|My bet is 24 caterpillars -|c| Rath111|GIMME DAT SHIT -|c|★Crime♥|oke i need a smoke.. -|c|★Crime♥|been playing for 5 hours now -|c|★CHEF BOY4RDEEZNUTS|smokers are jokers -|c| charizard8888|Replace player B4 leaving -|c| Rath111|lmao -|choice|move 4|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|290/386 par -|-damage|p2a: Heatran|242/386 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Heatran -|-resisted|p2a: Heatran -|-crit|p2a: Heatran -|-damage|p2a: Heatran|235/386 par -| -|-heal|p2a: Heatran|259/386 par|[from] item: Leftovers -|turn|792 -|c| anthonygmars|bruh i'll let you rape my ass -|c| anthonygmars|don't leave -|c| The Suicoon|how is this fun/ -|c|★Crime♥|crit mattered -|c| EL20|you should create a Rape room, anthony -|c|★CHEF BOY4RDEEZNUTS|its not -|c| EL20|so you can to yourself -|c| The Suicoon|what've you been doing all day? -|c| EL20|talk* -|choice|switch 5|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Heatran|[from]Magic Bounce -|drag|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|793 -|c| Gaussfield|this -|c| Gaussfield|they've been doing this -|c| LifeisDANK|the classy way to switch out -|choice|switch 2|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|259/386 par -|-damage|p2a: Heatran|211/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|602/642 -| -|-heal|p2a: Heatran|235/386 par|[from] item: Leftovers -|turn|794 -|c| LifeisDANK|is to magic bounce a roar -|c| Amber Torrey|Crime -|choice|switch 2|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Taunt|p1a: I <3 Stall -|move|p1a: I <3 Stall|Taunt|p2a: Heatran|[from]Magic Bounce -|-start|p2a: Heatran|move: Taunt -| -|-heal|p2a: Heatran|259/386 par|[from] item: Leftovers -|turn|795 -|c|★Crime♥|what? -|c|★Crime♥|dont flame me please -|c|★Crime♥|im justb attling -|c|★Crime♥|just battling* -|c|★CHEF BOY4RDEEZNUTS|hahah -|c| Crean|we should make this battle a room imo -|c| Amber Torrey|Idc about what people say -|c|★Crime♥|omg 5 more turns -|c| Amber Torrey|i'll battle yeah after this -|choice|switch 2|switch 5 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|796 -|c| MyHandSlipped|im gonna sleep now, if i wake up and the battle is still going im never playing again -|c| EL20|LOL -|c|★Crime♥|ahha -|c| LifeisDANK|800 HYPE -|choice|switch 4|switch 5 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Heatran|Heatran, F, shiny|259/386 par -|-damage|p2a: Heatran|211/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|235/386 par|[from] item: Leftovers -|turn|797 -|c| Amber Torrey|I'll use my IRL team -|choice|switch 2|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Taunt|p1a: I <3 Stall -|move|p1a: I <3 Stall|Taunt|p2a: Heatran|[from]Magic Bounce -|-start|p2a: Heatran|move: Taunt -| -|-heal|p2a: Heatran|259/386 par|[from] item: Leftovers -|turn|798 -|c| EL20|this battle almost has more turns than One Piece chapters -|c|★Crime♥|lol -|choice|switch 4|switch 5 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|799 -|c| Amber Torrey|And is as equally as fun... -|choice|switch 3|switch 4 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|switch|p2a: Cobalion|Cobalion|246/386 slp -|-damage|p2a: Cobalion|234/386 slp|[from] Stealth Rock -| -|turn|800 -|c| The Suicoon|isn't one piece in the 1100's? -|c| EL20|nope, 809 -|c| Amber Torrey|nah -|c| charizard8888|**800 TURNS** -|c|★Crime♥|omg 800 -|c| anthonygmars|continue! -|c| The Suicoon|i fell off of that ship long ago -|c| EL20|chef, crime, are you in the illuminati or what? -|c| PI EddyChomp|Lol -|c| LifeisDANK|WE are all reptilians -|c|★CHEF BOY4RDEEZNUTS|i want to leave but i also want crime to learn that he is not the best -|c| anthonygmars|stay and show him who's boss -|c|★Crime♥|lol -|c| LifeisDANK|Place your bets folks -|c|★Crime♥|im against the illuminati... -|choice|move 1|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|259/386 par -|-damage|p2a: Heatran|211/386 par|[from] Stealth Rock -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|189/386 par -| -|-heal|p2a: Heatran|213/386 par|[from] item: Leftovers -|turn|801 -|c| Amber Torrey|So you up to it Crime -|c| Amber Torrey|to fight me after this? -|c| anthonygmars|I believe in the ways of Trump -|c| LifeisDANK|you can only bet with half living caterpillars -|choice|move 1|move 2 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|193/386 par -|-unboost|p2a: Heatran|spa|1 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|217/386 par|[from] item: Leftovers -|turn|802 -|c| EL20|on another note, we have a 1420 rated player against a 1339 one. the match will end in a +/- 30+ -|c| LifeisDANK|so what will it be folks -|choice|switch 4|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Stealth Rock|p1a: I <3 Stall -|move|p1a: I <3 Stall|Stealth Rock|p2a: Heatran|[from]Magic Bounce -|-fail|p2a: Heatran -| -|-heal|p2a: Heatran|241/386 par|[from] item: Leftovers -|turn|803 -|c| charizard8888|Endless Battle Clause: Forcing endless battles is banned -|c| EL20|it's not endless you stupid za -|c| EL20|zard -|c|★Crime♥|exactly EL20 -|c| Amber Torrey|it kinda is -|c| LifeisDANK|its just long -|c|★Crime♥|<3 -|c| Rath111|el20 is mean -|c| LifeisDANK|long af -|c| EL20|i apologise then, rath -|c| TheCanadianWifier|wtf is goin on -|choice|switch 3|move 3 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|265/386 par|[from] item: Leftovers -|turn|804 -|c| The Suicoon|Who is the one stalling here though? -|c| EL20|you -|c| Amber Torrey|he can just keep switching to regen slowbro and that is a forced perma endless battle -|c| EL20|don't blame slowbro -|c|★CHEF BOY4RDEEZNUTS|crime more than me rn but he can still attack for the most part -|c|★Crime♥|!data mega slowbro -|c|~|/data-pokemon Slowbro-Mega - -|c|★Crime♥|he didnt evolve yet! -|choice|switch 3|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|289/386 par|[from] item: Leftovers -|turn|805 -|c| EL20|lel -|c|★CHEF BOY4RDEEZNUTS|regenerator spam -|c| LifeisDANK|I am gonna write a novel on the tale of the stall wars. much better than star wars -|choice|switch 3|move 3 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|move|p2a: Heatran|Stealth Rock|p1a: Fatty -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|313/386 par|[from] item: Leftovers -|turn|806 -|c| EL20|FINALLY -|c| TheCanadianWifier|OMG -|c| EL20|after 806 he gets rocks on -|choice|switch 5|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -|switch|p2a: Cobalion|Cobalion|234/386 slp -|-damage|p2a: Cobalion|222/386 slp|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|340/363|[from] item: Black Sludge -|turn|807 -|c| Orchestrite|forcing endless bans leppa berry with healing moves only -|c| TheCanadianWifier|is it over? -|c|~Zarel|The clause summary is just a summary; the basic idea is that forcing the opponent into a situation where they can't end the game is banned. All these people have to do is stop switching to progress the game. -|c| Amber Torrey|nah he will rapid spin them -|c|~Zarel|So Endless Battle Clause doesn't cover it -|c| PI EddyChomp|I guess it will be 1000 turns....? -|choice|move 4|move 2 -| -|-curestatus|p2a: Cobalion|slp -|move|p2a: Cobalion|Iron Head|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|281/363 -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|219/386 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -| -|-heal|p1a: U Jelly Bruh?|303/363|[from] item: Black Sludge -|turn|808 -|c| Crean|i hope so -|c| TheCanadianWifier|Zarel, I love you. Thanks for the hard work on the site ! -|c| EL20|sigh, can someone go for ONE kill? then you can stall how much you want -|c| LifeisDANK|that 0 damage -|c| Gaussfield|0% -|c|★Crime♥|0% -|c|★CHEF BOY4RDEEZNUTS|i cant kill anything -|c| Gaussfield|hooooooooly shit -|c| charizard8888|Let's all place bids on turns -|c| TheCanadianWifier|0% nice nice -|c| EL20|then kill one, crime -|choice|switch 6|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|313/352 tox -|move|p2a: Cobalion|Iron Head|p1a: Annoying AF -|-damage|p1a: Annoying AF|259/352 tox -| -|-heal|p1a: Annoying AF|303/352 tox|[from] ability: Poison Heal -|turn|809 -|c| EL20|at least one -|c| LifeisDANK|24 caterpillars to crime -|c| Rath111|1000 turns -|choice|move 4|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p1a: Annoying AF|347/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|810 -|c| breloomiswaifu|1100 turns -|choice|switch 5|switch 5 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|switch|p2a: Heatran|Heatran, F, shiny|313/386 par -|-damage|p2a: Heatran|265/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|289/386 par|[from] item: Leftovers -|turn|811 -|c| EL20|RIP gliscor -|c| TheCanadianWifier|PREDICTION TIME: -|c| TheCanadianWifier|1289 turns -|c| Amber Torrey|He can't out stall him when he keeps switching to slowbro -|c|★Crime♥|will we hit 900 turns? -|c| PI EddyChomp|Wow -|c| Amber Torrey|who can't die -|c| EL20|gliscor: 5 moves remaining, chansey: 5 moves remaining -|choice|switch 3|switch 5 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|812 -|c| Rath111|going to go play a league match -|c| Amber Torrey|unless crime literally wants him to -|c| Rath111|gonna see if this ends after it -|choice|switch 3|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|289/386 par -|-damage|p2a: Heatran|241/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|602/642 -| -|-heal|p2a: Heatran|265/386 par|[from] item: Leftovers -|turn|813 -|choice|switch 3|switch 5 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|814 -|c| EL20|chef, you can add cheat codes with F5 -|c| Amber Torrey|Chef will probably just leave at some point because it's a endless battle -|choice|move 4|switch 4 -| -|switch|p2a: Cobalion|Cobalion|219/386 -|-damage|p2a: Cobalion|207/386|[from] Stealth Rock -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-fail|p1a: I <3 Stall -| -|turn|815 -|c|★Crime♥|haha CHEF wants to go bed. -|choice|switch 5|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|347/352 tox -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|816 -|c|★Crime♥|820 turns+ -|c| Amber Torrey|This is literally just a battle on who wants to keep going -|c| LifeisDANK|hype -|c| lordkaelros|Wtf is this -|c|★Crime♥|but we are almost out of PP -|c| Amber Torrey|because this is endless -|c| EL20|let's boycott this game and leave -|c|★Crime♥|evetually we will run out of PP -|c|★CHEF BOY4RDEEZNUTS|yeah thats not skill its patience and pride -|c| EL20|let they choose what they want to do -|c|~Zarel|I bet CHEF will stop <3ing Stall after this -|c|★Crime♥|we cant keep switching.. -|c| CoolSwag2015|o zarel joined here -|c|★Crime♥|haha -|c|★Crime♥|nice one Zarel -|choice|switch 3|switch 5 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|switch|p2a: Heatran|Heatran, F, shiny|265/386 par -|-damage|p2a: Heatran|217/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|241/386 par|[from] item: Leftovers -|turn|817 -|c|~Zarel|I probably wasn't the first one to make that joke -|c| Amber Torrey|sense they both have switch -ins that can't die to struggle -|c| PI EddyChomp|Lol -|c|★Crime♥|maybe i should give heatran rest -|c|★Crime♥|lel -|c| Amber Torrey|gliscor with poison heal -|c| LifeisDANK|oml -|c|★CHEF BOY4RDEEZNUTS|i heart stall just not like this -|c|@Former Hope|Sounds antimeta -|c| sancnea|none dead till now? -|c| Amber Torrey|and slowbro with regen -|c| charizard8888|Everyone Share Replay when it gets over -|c| tuxedo_cat|You're right, you can't keep switching. Eventually, one of you will have a job or responsibility of some sort to attend to. -|c| jepler|WAIT WUT? -|choice|switch 5|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Stealth Rock|p1a: I <3 Stall -|move|p1a: I <3 Stall|Stealth Rock|p2a: Heatran|[from]Magic Bounce -|-fail|p2a: Heatran -| -|-heal|p2a: Heatran|265/386 par|[from] item: Leftovers -|turn|818 -|c| lordkaelros|Wait, so nothing died yet? -|c| EL20|tuxedo, best response ever -|choice|switch 5|move 3 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|move|p2a: Heatran|Stealth Rock|p1a: Fatty -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p2a: Heatran|289/386 par|[from] item: Leftovers -|turn|819 -|c| CoolSwag2015|turn 818 -|c| LifeisDANK|What is this responsibility you talk abou -|c| CoolSwag2015|6-6 -|c| lordkaelros|wow -|c| CoolSwag2015|im loving this -|c| charizard8888|12 Pokemons -|c| jepler|817 turns and still 6 pokes alive for both okayers o_O? -|c| drowzee518|how did this even happen? -|choice|move 3|move 4 -| -|move|p1a: Fatty|Wish|p1a: Fatty -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|313/386 par|[from] item: Leftovers -|turn|820 -|c|~Zarel|charizard8888, no, don't, the replay server can't handle replays this big anyway, you'll just get an error message -|c| EL20|boo -|c| EL20|fix the server -|c|~Zarel|there's a Download Replay button now, though! for posterity and all that -|c| CoolSwag2015|ima screenshot this when its over -|c| TheCanadianWifier|wait really? -|c| farty56 2.0|nothing has died yet? -|c| Amber Torrey|the replay would be to big -|c| drowzee518|tbh whoever forfeits is the real winner here -|c| anthonygmars|kill it! -|c| TheCanadianWifier|whats the apprx. limit for the replay server? -|c| TheCanadianWifier|like 200 turns -|c| EL20|big? meh -|c| TheCanadianWifier|? -|c| drowzee518|move on with ur life -|c| Amber Torrey|this replay would be around 10 g's -|c| drowzee518|forl -|choice|switch 6|move 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|303/363 -|-damage|p1a: U Jelly Bruh?|258/363|[from] Stealth Rock -|move|p2a: Heatran|Taunt|p1a: U Jelly Bruh? -|-start|p1a: U Jelly Bruh?|move: Taunt -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] move: Wish|[wisher] Fatty -|-heal|p2a: Heatran|337/386 par|[from] item: Leftovers -|turn|821 -|c| Danscott|wtf is happening -|c| tuxedo_cat|I give up. -|c|~Zarel|I'll manually upload the replay to the replay server, the rest of you don't need to do anything -|c| sancnea|damn zarel inerfering -|c| drowzee518|rofl* -|c| tuxedo_cat|I've been here long enough. -|c| sancnea|thats new -|c| TheCanadianWifier|Thank you :] -|c| LifeisDANK|I believe in you you got this! -|c| charizard8888|Okay Zarel -|c|★CHEF BOY4RDEEZNUTS|he could make it a tie -|c| QuagGod|holy jesus -|c| tuxedo_cat|Ya both talentless hacks, and combatitive frauds. -|c| QuagGod|o_o -|c|★CHEF BOY4RDEEZNUTS|;) -|c| EL20|zarel is my God -|c| charizard8888|^ -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|332/386 par -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|356/386 par|[from] item: Leftovers -|turn|822 -|c|@Former Hope|"Come play Pokemon Showdown, enjoy 1000+ turn battles!" -|choice|switch 6|move 4 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|380/386 par|[from] item: Leftovers -|turn|823 -|c| lordkaelros|26 rapid spins left -|c| CoolSwag2015|looooool -|c| lordkaelros|woohoo -|choice|switch 5|switch 5 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|824 -|c| EL20|seismic toss FTW -|c| sancnea|no knock off? -|c| charizard8888|3 wish 1 Toxic -|c|★Crime♥|hey guys -|c| jepler|I just went to see the credits and I came here to see Zarel wow what a stroke of luck -|c| QuagGod|zarel ur the homie :) -|c|~Zarel|TheCanadianWifier, I don't remember the limit, but I think it's around 200 turns? -|c| EL20|sigh, it's not funny anymore -|c|★Crime♥|we still have 2 wishes left -|c|★Crime♥|<3 -|c| drowzee518|how long ago did this battle start? -|c| Danscott|i'm nott seein anything -|c|★Crime♥|the game didnt start yet -|c| EL20|824 ago? -|c| Danscott|'-' -|c| Amber Torrey|Crime you didn't answer me will you fight me after this? -|c|%Quite Quiet|the solution is to not have a full stall team without a way to beat opposing stall -|c|★Crime♥|6 hours ago drowzee518 -|c| PI EddyChomp|See -|c| TheCanadianWifier|that's what I guessed, yea that seems reasonable. -|c|★Crime♥|no amber im very tired -|c|★Crime♥|lol -|c|★Crime♥|my back hurts -|c|★Crime♥|my eyes are falling out -|c| CoolSwag2015|LOL 6 hours -|c|★Crime♥|and i want to smoke -|c| lordkaelros|lmao -|c| Amber Torrey|Weakling -|c| drowzee518|this actually took 6 hours? -|c|+SpaceBass|The solution is to play DOU where stall is unviable :) -|c| lordkaelros|The dedication is real -|c| TheCanadianWifier|LOL 6 hours -|c|★Crime♥|yes i am a weakling staller -|c|@Former Hope|Or just play 1v1 -|c|★CHEF BOY4RDEEZNUTS|no idea how long its been -|c| EL20|think about the electricity you've been using, could have been used for something with more purpose -|c| drowzee518|i would take 2141 losses to not waste 5 hours -|c| jepler|Lesson Learned always have taunt for STALL TEAMS -|c| LifeisDANK|guys Im gonna build a mine here so i can harvest all this salt -|c| Amber Torrey|Stalling doesn't make you a weakling -|c| PI EddyChomp|.................................................................................................................................................................................................................................................... -|c| CoolSwag2015|i love this battle -|c|★CHEF BOY4RDEEZNUTS|weakling because he wont attack me -|c| Amber Torrey|being a weakling makes you a weakling -|c|★Crime♥|oke amber -|c| PI EddyChomp|Exactly -|c|★Crime♥|you're so much better than me -|c| i am having fun|hm 800 turns and 6-6 -|c| hey i'm pikachu|WHAT IS HAPPENING -|c| i am having fun|ok -|choice|switch 5|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|380/386 par -|-damage|p2a: Heatran|332/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|602/642 -| -|-heal|p2a: Heatran|356/386 par|[from] item: Leftovers -|turn|825 -|c| hey i'm pikachu|LAGGING -|c| drowzee518|the points arent worth 6 hours -|c| PI EddyChomp|I KNOW -|c| GonxKillua|this lag -|c| Amber Torrey|Never said i was better then you -|c| Danscott|i hate stall -|c| sancnea|ikr? -|c| LifeisDANK|Hi pikachu welcome to the war! the GReat Stall WAr -|c| Amber Torrey|What a weakling -|c|★Crime♥|omg turn 900 -|c|★Crime♥|soon -|choice|switch 5|switch 5 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|826 -|c| Amber Torrey|He folds so easily... -|c| Gaussfield|"soon" -|c| sancnea|soon? -|c| sancnea|lol -|c| CoolSwag2015|zarel nice avatar btw n.n -|choice|switch 5|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|356/386 par -|-damage|p2a: Heatran|308/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|602/642 -| -|-heal|p2a: Heatran|332/386 par|[from] item: Leftovers -|turn|827 -|c| EL20|yeah i'm fed up with all of you -|c| LifeisDANK|:( -|c| LifeisDANK|but ily -|choice|switch 6|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|828 -|c| lordkaelros|slowbro still healthy as fuck -|c| CriclesAreRound|man this almost crashed my phone -|c| lordkaelros|So this isn't gonna end -|c|★Crime♥|lol -|c| PI EddyChomp|How long will this **LAST?** -|choice|switch 6|switch 5 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|switch|p2a: Heatran|Heatran, F, shiny|332/386 par -|-damage|p2a: Heatran|284/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|308/386 par|[from] item: Leftovers -|turn|829 -|c| hey i'm pikachu|just loaded 700 turns -|c| Amber Torrey|Because slowbro literally can't die -|c| lordkaelros|They're just gonna keep swapping -|c| Amber Torrey|unless crime literally makes him -|c| hey i'm pikachu|200 more to go -|c| jepler|there's only one thing TO DO switch pokes until we reach turn 999 -|c| sancnea|pls stop -|c|★CHEF BOY4RDEEZNUTS|im forced to swap he can still attack -|c| lordkaelros|What happens at 999 -|choice|switch 5|switch 5 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|830 -|c| CoolSwag2015|this was so close to crashing my laptop -|c| Danscott|the battle is stil hapening? -|c| LifeisDANK|same -|c| Durr00|MY PC IS LAGGATTLEING AND I CANT SEE SHIT OF THIS B -|c| QuagGod|same -|c| QuagGod|lol -|c| CoolSwag2015|it froze for like 2 minutes -|c| Aluminion|just knock it off already -|c| charizard8888|Yup Danscott -|choice|switch 5|move 3 -| -|switch|p1a: Fatty|Chansey, F|602/642 -|move|p2a: Slowbro|Toxic|p1a: Fatty -|-status|p1a: Fatty|tox -| -|-damage|p1a: Fatty|562/642 tox|[from] psn -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|831 -|c| Aluminion|nvm -|c|@Former Hope|You aren't forced to switch, if you can't attack you pretty much already lost -|c| Vicky★the✡Shitlord|top lag -|c|★Crime♥|hes out of knock off -|c| CoolSwag2015|i love this battle -|c| CoolSwag2015|<3 -|c| lordkaelros|No more heal bells -|c| CriclesAreRound|will this even upload?lol -|c| Vicky★the✡Shitlord|battle aint even loading for me -|c| LifeisDANK|this is my fav battle of all time -|c| Danscott|burn the florges -|c| charizard8888|3 wish 1 toxic -|c| CoolSwag2015|criclesareround, zarel said that he would manually upload it -|c|★Crime♥|florges op -|c|★Crime♥|!data florges -|c|~|/data-pokemon Florges - -|c| Gaussfield|i don't want this day to end -|c| i am having fun|pp stall and let hazards win? -|c| hey i'm pikachu|finally -|c| The Suicoon|it's about to get colossal -|c| hey i'm pikachu|loaded -|c| PI EddyChomp|Lol -|c| hey i'm pikachu|831 turn -|c| Aluminion|but chansey has natural cure....... -|c| lordkaelros|lol -|c| Vicky★the✡Shitlord|uh -|c| lordkaelros|oops -|choice|switch 2|switch 4 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Cobalion|Cobalion|207/386 -|-damage|p2a: Cobalion|195/386|[from] Stealth Rock -| -|turn|832 -|c| PI EddyChomp|Can someone voice me? -|c| charizard8888|Circlesareround don't upload it -|choice|switch 5|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|308/386 par -|-damage|p2a: Heatran|260/386 par|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|-heal|p2a: Heatran|284/386 par|[from] item: Leftovers -|turn|833 -|c| charizard8888|Zarel will manually do it -|c| Danscott|he uses cobalion and florges that is cool -|c| CriclesAreRound|of course i wont -|c| Vicky★the✡Shitlord|ok -|c| sancnea|stealth rocks for the win -|c| hey i'm pikachu|how can u love stall -|c| Danscott|i love exotic pokemons '-' -|c| Vicky★the✡Shitlord|833 -|c| Vicky★the✡Shitlord|nice -|c| hey i'm pikachu|lol -|c| CoolSwag2015|so this will just be a game of switches -|c| PI EddyChomp|WE NEED YOUTUBE CHANNELS -|c| CoolSwag2015|and occasional attacking -|c| CriclesAreRound|crashing my phone -|c| charizard8888|^^ -|c| QuagGod|pretty much coolswag2015 -|c| PI EddyChomp|UPLOAD THESE BATTLES -|c| CoolSwag2015|yeah i love this -|c| PI EddyChomp|GET LOADS OF MONAY -|c| Aluminion|this is why i hate stall teams -|c| LifeisDANK|Woop woop -|c| drowzee518|this is such a waste of time -|c| PI EddyChomp|MONEY* -|c| sancnea|wait how could he have used that many calm minds? -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|834 -|c| jepler|I have a youtube account actually -|c| Gaussfield|it's never a waste of time -|c| Danscott|a sword dancer would fix this -|c| LifeisDANK|why so many salty people this aint your battle -|c| Aluminion|(though i have a stall team myself with slowbro, amoonguss and tornadus) -|c| sancnea|and still not finish the game? -|c| Aluminion|you all know how that goes -|c| Gaussfield|when it goes this far -|c| CriclesAreRound|send this to all youtubers u know -|c| charizard8888|5 Recover 3 Will o wisp -|c| jepler|but I don't do uploads cuz I'm still a kid lolz -|c| QuagGod|this my frens -|choice|switch 5|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|284/386 par -|-damage|p2a: Heatran|236/386 par|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-heal|p2a: Heatran|260/386 par|[from] item: Leftovers -|turn|835 -|c| Amber Torrey|No idea why people are still calling this a battle -|c| QuagGod|is why we bring proper stallbreakers on stall -|c| Amber Torrey|because it's not -|c| LifeisDANK|this is a lesson -|c| LifeisDANK|and an experience -|c| LifeisDANK|its art -|c| QuagGod|^ -|choice|switch 5|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Taunt|p1a: I <3 Stall -|move|p1a: I <3 Stall|Taunt|p2a: Heatran|[from]Magic Bounce -|-start|p2a: Heatran|move: Taunt -| -|-heal|p2a: Heatran|284/386 par|[from] item: Leftovers -|turn|836 -|c| QuagGod|*-* -|c| Durr00|why is this battle taking so long without anyone fainting yet? -|c| Aluminion|lol -|c| anthonygmars|what move are we on again? -|c| anthonygmars|lol -|c| LifeisDANK|determination dear lad -|choice|move 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|837 -|c| Amber Torrey|Because both teams are pure stall pokemon -|c| CoolSwag2015|Turn 837 -|c| CoolSwag2015|woo -|choice|switch 6|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|838 -|c| lordkaelros|I don't think he <3 stall anymore -|c| sancnea|wow they actually used moves -|c| Aluminion|jirachi isn't that stall -|c| Danscott|charizard y would be a problem to CHEF -|c| CoolSwag2015|this is longer than the time i used harvest leppa splash karp -|c| Amber Torrey|Jirachi is plenty of stall -|c| hey i'm pikachu|best solution: -|c| CriclesAreRound|was this random opponent or challenge battle -|c| QuagGod|aluminion rachi works on stall fam -|c| hey i'm pikachu|ban recovery -|choice|move 4|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|284/386 par -|-damage|p2a: Heatran|236/386 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|232/386 par -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|turn|839 -|c| PI EddyChomp|Or ban Para -|c|★Crime♥|random opponent -|c| Gaussfield|i clicked on switch sides and HOO BOY -|c|★Crime♥|this is a legit OU battle -|c| drowzee518|best solution: one of these players has something irl to do -|c| lordkaelros|Holy fuck -|c|@Former Hope|Just ban everything and then nothing will be broken or OP -|c| Aluminion|24 more rapid spins -|c| LifeisDANK|yeah switching sides resets the page pmuch -|c| CoolSwag2015|lol -|c| charizard8888|Switch sides : forever to load -|c| sancnea|ban 10 switches ina row -|c| Danscott|a pokemon with only offensive attacks huahuahua -|choice|switch 5|move 1 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Heatran|Lava Plume|p1a: TheMoreYouKnow -|-supereffective|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|205/403 -| -|-heal|p1a: TheMoreYouKnow|230/403|[from] item: Leftovers -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|840 -|c| Aluminion|2 stealth rocks -|c| LifeisDANK|#banpokemon -|c| QuagGod|former hope but then what'll counter our lord and savior magikarp??? -|c| lordkaelros|plaid -|c| CriclesAreRound|hey i'm pikachu we should ban u for that name and not ban recovery -|c| sancnea|wow! damage -|choice|switch 2|move 2 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|304/386 par|[from] item: Leftovers -|turn|841 -|c|★CHEF BOY4RDEEZNUTS|2 left bro -|c| hey i'm pikachu|noooooooooooooooo -|c| sancnea|i finally saw it -|c|★CHEF BOY4RDEEZNUTS|use em up -|c| PI EddyChomp|LOL -|c|★Crime♥|never -|c|★Crime♥|im not you who runs out of moves -|c| QuagGod|so when's the first blood -|c| Danscott|para is good for crime -|c| sancnea|man 2 chaneys -|c| Danscott|he will lost less pp's -|c| LasagnaIsRectangle|wow -|c|★Crime♥|yes -|c|★Crime♥|i need more pars -|choice|switch 6|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Taunt|p1a: I <3 Stall -|move|p1a: I <3 Stall|Taunt|p2a: Heatran|[from]Magic Bounce -|-start|p2a: Heatran|move: Taunt -| -|-heal|p2a: Heatran|328/386 par|[from] item: Leftovers -|turn|842 -|c|@Former Hope|Said no pokemon player until now -|c| Aluminion|lol -|c| PI EddyChomp|LOL -|c| Gaussfield|in the event of a struggle war -|c| QuagGod|gottem -|c|★CHEF BOY4RDEEZNUTS|once you run out youll just switch endlessly -|c| sancnea|clefable -|c|★CHEF BOY4RDEEZNUTS|but i have rocks -|c| sancnea|skarm -|c| Gaussfield|para would be op -|c| CriclesAreRound|lol -|c| Amber Torrey|Hmm pretty sure he has switched into slowbro over 350 times for regen switch stalling -|c|★Crime♥|hey guys -|c|★Crime♥|we still have skarmory! -|c| LasagnaIsRectangle|longest battle -|c|★Crime♥|and florges! -|c|★CHEF BOY4RDEEZNUTS|THANK YOU AMBER TORREY -|c| PI EddyChomp|Lol -|c|★Crime♥|no amber -|c| Aluminion|skarmory can just defog lol -|c| sancnea|man knock off all lefties and let rocks do the job -|c|★CHEF BOY4RDEEZNUTS|CRIME YOURE FULL OF SHIT -|c| Orchestrite|any mons with knock off here? -|c| Danscott|i wanna see this sableye burn -|c| hey i'm pikachu|leftovers should make your pokemon rotten -|c| i am having fun|rocks win -|c| sancnea|oh yeah... no knock off -|c| PI EddyChomp|Lol -|c|★Crime♥|we both switch stalled after turn 600+ -|c| lordkaelros|knock pp long gone -|c|★CHEF BOY4RDEEZNUTS|he has 1 defog i have 5 rocks -|c|★CHEF BOY4RDEEZNUTS|or something -|c| LifeisDANK|can we appreciate the amount of time these two put into this 6-6 battle -|c|★Crime♥|1 defog is enough -|c| lordkaelros|wait, sableye doesn't have knock off -|c|★CHEF BOY4RDEEZNUTS|i cant attack bro -|c| QuagGod|turn off timer fam -|c| QuagGod|pls -|c|★CHEF BOY4RDEEZNUTS|all i can do is bait you -|c| drowzee518|if i finish my 1500 word paper before u guys finish thats kinda sad -|c| Kuronachan|I hate everything about this -|c| The Suicoon|why can't you attack him? -|c| LifeisDANK|you got this drowzee -|c| hey i'm pikachu|i bet this chat takes more lines than the whole battle -|c| Kuronachan|This battle is killing me -|c| LifeisDANK|write them words -|c| Aluminion|he can stall out ur 5 rocks first though -|c| BayFence|this battle is for cheef -|c| Danscott|victini would destroy this team '-' -|c| sancnea|now timer stalling? -|choice|switch 3|switch 4 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|843 -|c| Aluminion|coz crime has more moves in total -|c| ZzamanN|And this is exactly why there is an in game timer -|c| QuagGod|rip kurona's browser yn -|c|★CHEF BOY4RDEEZNUTS|rapid spin, flamethrower, and moonblast dont do shit -|c| Kuronachan|this took like five minutes to load -|c|★CHEF BOY4RDEEZNUTS|especially with the switch stall -|choice|move 3|switch 4 -| -|switch|p2a: Heatran|Heatran, F, shiny|328/386 par -|-damage|p2a: Heatran|280/386 par|[from] Stealth Rock -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|264/352 tox -| -|-heal|p2a: Heatran|304/386 par|[from] item: Leftovers -|-heal|p1a: Annoying AF|308/352 tox|[from] ability: Poison Heal -|turn|844 -|c|★Crime♥|lol -|c| Kuronachan|i had to watch shitty toy reviews while waiting -|c| hey i'm pikachu|stall=protect every other turn -|c| charizard8888|This VDO is viral -|c| lordkaelros|Whatchu gonna do with that sub bro -|c| Danscott|for a world without stall '-' -|c| CoolSwag2015|6-6 turn 844 -|c| lordkaelros|It's not like you have any attacks -|c| Aluminion|just switch lol gliscor can't do fuck -|c|★CHEF BOY4RDEEZNUTS|using my pp cause im not a bitch -|choice|switch 3|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Heatran|[from]Magic Bounce -|drag|p2a: Chansey|Chansey, F|374/642 -|-damage|p2a: Chansey|294/642|[from] Stealth Rock -| -|turn|845 -|c|★Crime♥|omg -|c| charizard8888|Annoying 2 Sub + 2 Protect -|c| Aluminion|lol rekt -|c| lordkaelros|played -|c| QuagGod|gottem -|c| charizard8888|LOL the Prediction -|c| LifeisDANK|aYYyy -|c| ZzamanN|deez nuts -|c| PI EddyChomp|THIS BATTLE THO -|c| hey i'm pikachu|gg -|c| hey i'm pikachu|not good game -|c| Kuronachan|endless battle clause -|c|★CHEF BOY4RDEEZNUTS|HE HAS A SOFTBOILED LEFT UGH -|c| LifeisDANK|best battle of allll time -|c| Kuronachan|clearly needs to have more rules -|c| Palace Dawson|mMEOW -|choice|move 3|move 3 -| -|move|p2a: Chansey|Soft-Boiled|p2a: Chansey -|-heal|p2a: Chansey|615/642 -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Chansey -|-status|p2a: Chansey|brn -| -|-damage|p2a: Chansey|535/642 brn|[from] brn -|turn|846 -|c| Amber Torrey|Not much of a prediction when he always uses roar on a subbed gliscor -|c| LasagnaIsRectangle|put in world longest battle -|c| hey i'm pikachu|there -|c| sancnea|yay -|c| hey i'm pikachu|full -|c| Aluminion|natural cure lol -|choice|switch 3|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|308/352 tox -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|847 -|c| charizard8888|23 Seismic Tosses -|c| sancnea|no more softboil -|choice|switch 5|switch 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Heatran|Heatran, F, shiny|304/386 par -|-damage|p2a: Heatran|256/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|848 -|c| Kyorem|is this still goin -|c| LifeisDANK|you betcah -|c| Kyorem|this took -|c|★Crime♥|lol -|c| Nortellaz|I'm guessing the two of you are only continuing the battle out of principle rather than actually caring for the points. -|c| PI EddyChomp|I think there will be 946 turns -|c| charizard8888|__Struggle__ to end the fight -|c| Kyorem|5 minutes + to load -|c| charizard8888|^ -|c| hey i'm pikachu|10 hours -|c|★Crime♥|yes nortellaz -|c| Nortellaz|If the latter, that's really, really, REALLY sad -|c| hey i'm pikachu|4 me -|c| CoolSwag2015|took me 2 minutes -|c| Funkytoucan|turn 100 the dream -|c| Aluminion|if it comes down to the wire crime will just switch between slowbro (who has regen) and coba (who takes jackshit from stealth rock -|c| lordkaelros|*1000 -|c| PI EddyChomp|MAKE IT 900 TURNS -|c| Funkytoucan|*1000 -|c| LifeisDANK|Only the stalliest will survive -|c|★Crime♥|the whole lobby is in this game -|c| CriclesAreRound|1000 -|c| PI EddyChomp|U CAN DO IT -|c| CoolSwag2015|loool -|c| charizard8888|Don't Stop -|c| LasagnaIsRectangle|if this battle is in oras , i bet it will a draw because there is a time -|c| charizard8888|Play fast -|c|★CHEF BOY4RDEEZNUTS|i hope the site crashes -|c| LifeisDANK|ILY bby -|c| BayFence|come on chef u can win this -|choice|switch 3|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|304/386 par|[from] item: Leftovers -|turn|849 -|c|+SpaceBass|Inb4 someone disconnects -|c| Asada Shino San|I can't see shit -|c|~Zarel|took me around 12 seconds, if you're wondering what a powerful computer is like :) -|c| hey i'm pikachu|stealth rock should do 25% -|c| charizard8888|40 Secs left -|c| Amber Torrey|Both sides if both run of PP have endless battle pokemon -|c| PI EddyChomp|Nope -|c| charizard8888|**Turn off the timer** -|choice|switch 6|move 4 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|move|p2a: Heatran|Taunt|p1a: Fatty -|-start|p1a: Fatty|move: Taunt -| -|-heal|p2a: Heatran|328/386 par|[from] item: Leftovers -|turn|850 -|c| hey i'm pikachu|and 100%to charizard -|c| Amber Torrey|gliscors poison heal and slowbros regen -|c| Kyorem|Zarel pls -|c| QuagGod|**turn off timer pls** -|c| LifeisDANK|Turn UP the timer -|c| Vicky★the✡Shitlord|it took me like 50 seconds ?_>? -|c| QuagGod|fr tho -|c| QuagGod|lol -|c| anthonygmars|so what move are we on? -|choice|switch 6|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Heatran|[from]Magic Bounce -|drag|p2a: Florges|Florges, F|252/360 -|-damage|p2a: Florges|207/360|[from] Stealth Rock -| -|turn|851 -|c| XXawesomenessXX|lol 850 turns without a single fainted pokemon -|c| Vicky★the✡Shitlord|rawr -|c| The Suicoon|took me about 30 secs -|c| i am having fun|imagine loading this on a phone -|c| PI EddyChomp|But if the server has to restart, you are in luck. -|c|★Crime♥|florges in action -|c| i am having fun|shieet -|c| hey i'm pikachu|spoiler:18 moonblasts -|c| Vicky★the✡Shitlord|i am having fun, it would probably be impossible -|c| lordkaelros|florges gonna sweep bois -|c| charizard8888|1 Protect , 1 Wish , 18 Moonblast -|c|★CHEF BOY4RDEEZNUTS|JOHN CENAAAAAA -|c| Nortellaz|Tentacruel can absorb that shit right up anyway -|c| LifeisDANK|Im having a good time -|c|@Former Hope|Now just imagine this game if Zarel hadn't added the PP tracker -|c| PI EddyChomp|Spoiler: 999999 Struggles......? -|c| QuagGod|florges going in for the sweep -|c| QuagGod|*-* -|c| Amber Torrey|florges can't do anything -|c| Kyorem|Zarel what would happen if someone uploaded the reply for this lol -|c| Amber Torrey|chansey walls it -|c| Asada Shino San|finally I get a screen -|choice|switch 3|switch 2 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|852 -|c| Vicky★the✡Shitlord|hi shrang -|c|@Former Hope|Kyorem, you couldn't -|c| go for busted|>seeking -|c| hey i'm pikachu|best game -|choice|switch 6|switch 5 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|switch|p2a: Cobalion|Cobalion|195/386 -|-damage|p2a: Cobalion|183/386|[from] Stealth Rock -| -|turn|853 -|c| go for busted|finally -|c| Kyorem|no? :[ -|c|★Crime♥|i have a good idea -|c|@Former Hope|It would have to be made manually since it won't make the replay past a certain number of turns -|c| hey i'm pikachu|0 deaths -|c| LasagnaIsRectangle|u can do it!!! -|c| hey i'm pikachu|how peaceful -|c| hey i'm pikachu|stall is peace -|c|★Crime♥|awe Former hope -|c| go for busted|mega sab isn't broken -|c| hey i'm pikachu|the best playstyle -|c| Aluminion|dare you to stay in chef -|c| CoolSwag2015|~Zarel: I'll manually upload the replay to the replay server, the rest of you don't need to do anything -|c| CoolSwag2015|Kyorem -|c| XXawesomenessXX|this is what happens if both teams are defensive -|c| LasagnaIsRectangle|lol -|c| charizard8888|go for busted have you named yourself after CANDACE from Phineas and Ferb ? -|c| Kyorem|Oh sick lol -|c| PI EddyChomp|Did anyone read my Spoiler? -|choice|switch 3|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|854 -|c| charizard8888|yup -|c| TLC1 parivar|hmmm -|c| MightySwagger013|PI EddyChomp 18 moonblasts -|c| go for busted|I named myself after your mom -|c| go for busted|ayy lmoa -|c| SingingTacos|this battle is so long that the mons are not even showign for me -|choice|switch 6|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|855 -|c| LasagnaIsRectangle|IMOA -|c| Kuronachan|oh look nothing got done that turn -|c| PI EddyChomp|Spoiler: 999999999999 Attacks and Struggles. -|c| SingingTacos|,3, -|c| hey i'm pikachu|**wasted** -|c| LifeisDANK|Time to get switchy in here -|c| Aluminion|scald burn -|c| go for busted|how long have pebbles been up -|c| Aluminion|u can do this -|c|★Crime♥|3 scals -|c| SingingTacos|is this the longest battle on ps -|c|★Crime♥|scalds* -|c| QuagGod|oh fuck -|c| QuagGod|i think my comp is giving in -|c| i am having fun|long time go for busted -|c| SingingTacos|i thought the longest was like 1000 -|c| LasagnaIsRectangle|0 scald left -|c| QuagGod|noo ;_; -|c| Kuronachan|just use a move to use up PP already -|choice|switch 2|switch 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|230/403 -|switch|p2a: Heatran|Heatran, F, shiny|328/386 par -|-damage|p2a: Heatran|280/386 par|[from] Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|255/403|[from] item: Leftovers -|-heal|p2a: Heatran|304/386 par|[from] item: Leftovers -|turn|856 -|c| SingingTacos|rip scalds -|c| lovemathboy|omg how many turns is this -|c| Asada Shino San|dem switches -|choice|move 2|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-heal|p1a: TheMoreYouKnow|280/403|[from] item: Leftovers -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|857 -|c| LasagnaIsRectangle|856 -|c| lovemathboy|it's loading -|c| Aluminion|lol -|c| CoolSwag2015|857* -|c| Kuronachan|fcuKING SWiTchES -|c| CoolSwag2015|kek -|c| PI EddyChomp|........................................ -|choice|switch 3|switch 3 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|switch|p2a: Heatran|Heatran, F, shiny|304/386 par -|-damage|p2a: Heatran|256/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|858 -|c| LasagnaIsRectangle|when is this going to end -|c| lovemathboy|OMG IT FINISHED LOADING -|c| SingingTacos|emm -|c| charizard8888|It will take 5 mins to load -|c| Kyorem|Zarel what comp do you have ? -|c| The Suicoon|how is this going to end? -|c| Amber Torrey|man look at all those slowbro regen switch-ins -|c| SingingTacos|do you guys get anything from this -|c| sancnea|ban switching... -|c| Wasim007|this battle will crash the servers -|c| lordkaelros|satisfaction -|c|★Crime♥|bann switching would be unfair, cause we have a different team -|c| hey i'm pikachu|what happens at 1000 -|c|★Crime♥|unfornately. -|c| LasagnaIsRectangle|idk -|c| LifeisDANK|we party -|c| Aluminion|this server is written in 10 bit binary -|c|★Crime♥|the game will automaticly end -|c| Aluminion|it wil only go up to 1024 -|choice|switch 6|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Heatran|[from]Magic Bounce -|drag|p2a: Cobalion|Cobalion|183/386 -|-damage|p2a: Cobalion|171/386|[from] Stealth Rock -| -|turn|859 -|c| LifeisDANK|WE SHALLFIND OUT -|c| LasagnaIsRectangle|celebrate the longest battle to the chef and chime -|c| hey i'm pikachu|**same play** -|c| QuagGod|someone -|c| LifeisDANK|hype -|c| PI EddyChomp|YEAH -|c| QuagGod|pls turn off the timer -|c| QuagGod|jesus -|c| CriclesAreRound|has there ever been a longer one -|c| SingingTacos|i think funbro -|c| Wasim007|wake me up when its over -|c| Aluminion|what are your ratings -|c|+Frizy|funbro dont count -|choice|switch 4|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Redbull|Clefable, M|393/393 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|860 -|c| Amber Torrey|Yes longer battles exist -|c| SingingTacos|was the longest one -|c|★Crime♥|over 40 mins we are playing for 7 hours i think -|c| LasagnaIsRectangle|nope iirc -|c| PI EddyChomp|__Font abuse for longest **BATTLE!!**__ -|c| LifeisDANK|Wake me up -|c| LifeisDANK|wake me up inside -|c| PI EddyChomp|LOL -|c| Aluminion|PLEASE ANSWER: what are your elo ratings -|c| CriclesAreRound|what is funbro? -|c| PI EddyChomp|Redbull -|c|+Frizy|rip earthworms 716 turn gsc battles -|c|★Crime♥|no redbull unhealthy -|c|@Former Hope|Aluminion, you can use /rank username -|c| Aluminion|thx -|choice|switch 3|switch 5 -| -|switch|p1a: TheMoreYouKnow|Jirachi|280/403 -|switch|p2a: Heatran|Heatran, F, shiny|280/386 par -|-damage|p2a: Heatran|232/386 par|[from] Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|305/403|[from] item: Leftovers -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|turn|861 -|c| LasagnaIsRectangle|keep going -|c|★CHEF BOY4RDEEZNUTS|redbull is life -|c| SingingTacos|**Em what do you guys get from this. Like +7 points in ladder?" -|c| CriclesAreRound|golduck is life -|c| LifeisDANK|redbull is gross tbh -|c| anthonygmars|WHAT MOVE ARE WE ON? -|c| CriclesAreRound|861 -|c| Asada Shino San|861 -|c| SingingTacos|**Em what do you guys get from this. Like +7 points in ladder?** -|choice|switch 4|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Taunt|p1a: I <3 Stall -|move|p1a: I <3 Stall|Taunt|p2a: Heatran|[from]Magic Bounce -|-start|p2a: Heatran|move: Taunt -| -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|862 -|c| Kuronachan|1 -|c| Aluminion|they're in the 1300's -|c| XXawesomenessXX|861 -|c| drowzee518|the points are not worh it at all -|c| Aluminion|rating -|c| drowzee518|even if u got 200 point -|c| LasagnaIsRectangle|0 uturn and ironhead rip -|c| drowzee518|s -|c|★CHEF BOY4RDEEZNUTS|i dont care bout points -|c| Aluminion|so it doesn't matter that much -|c| LifeisDANK|its not about the points...its about sending a message -|c| QuagGod|i dont think -|c| PI EddyChomp|**THER WILL BE 999999 TURNS!!** -|c| QuagGod|they care -|c|★CHEF BOY4RDEEZNUTS|dank u right -|c| QuagGod|about points -|c| Kuronachan|this is taking longer than goku's charge up time -|c|★Crime♥|omg -|c| XXawesomenessXX|☺☻☺☻☺ -|c|★Crime♥|900 turns soon -|c| Aluminion|for all this time i thought it was like 1600 or something -|choice|switch 6|switch 5 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|863 -|c| QuagGod|if they're expecting matches like this -|c| QuagGod|lol -|c| LifeisDANK|Dank always right ,':) -|c| LasagnaIsRectangle|later all 0 PP -|c| Aluminion|coz u 2 are playing immaculately -|c| SingingTacos|**GO to 1000 :^)** -|c| sancnea|noones going to forfei -|c| PI EddyChomp|This might take 100 Hours -|c| LasagnaIsRectangle|only sharpen -|choice|switch 3|switch 5 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|switch|p2a: Heatran|Heatran, F, shiny|280/386 par -|-damage|p2a: Heatran|232/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|turn|864 -|c| Amber Torrey|These are the kind of watches that get things on the site banned from use -|c| Kuronachan|go to 1024 -|c| LasagnaIsRectangle|lol -|c| PI EddyChomp|__**100 HOURS**__ -|c| CriclesAreRound|just switch mindlessly -|c| sancnea|if they leave they wont even tell the other -|c| SingingTacos|~~inb4 next suspect test is Stall~~ -|c| LasagnaIsRectangle|0 PP left for all moves -|c| XXawesomenessXX|666 Decades -|c| Kyorem|how long in terms of time have you two been here for Crime and CHEF? -|c| charizard8888|^ -|c| breloomiswaifu|just 6 moar hours mom! -|c| CoolSwag2015|7 hours -|c| The Suicoon|7 hours -|c| hey i'm pikachu|spoiler: mold breaker swords dance haxours -|c| sancnea|just let the timer do its thing -|c| AtmaARMS|crean, you still alive in here? -|c| QuagGod|singingtacos does msab suspect count -|c|★CHEF BOY4RDEEZNUTS|no idea -|c| Wasim007|reminsd me of battle of Ash with metapod vs metapod in the anime -|c| hey i'm pikachu|defeat that unaware -|c|★CHEF BOY4RDEEZNUTS|im dying inside -|c| hey i'm pikachu|quag -|c| SingingTacos|msab suspect test was crap af lol -|c| LasagnaIsRectangle|tooo long -|c|★CHEF BOY4RDEEZNUTS|METAPOD USE HARDEN -|c| Asada Shino San|keep going bruh -|choice|switch 3|move 2 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|865 -|c| gutu170599|longest battle imo is 6492 turns -|c| sancnea|aww cmon -|choice|switch 6|switch 5 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|866 -|c| CriclesAreRound|wtf -|c| QuagGod|jesus christ -|c| PI EddyChomp|Oh I heard you like Mudkips? -|c| QuagGod|just turn off the fking timer -|c| SingingTacos|this is why -|c|★Crime♥|i cant put the timer off -|c| LasagnaIsRectangle|just going to nap first -|c| drowzee518|wanna here something funny -|c| LifeisDANK|dootdootdootdootdootdodododoot Its the final countdown -|c| SingingTacos|there needs to be a playstle that revovles around taunt -|c| LifeisDANK|jk -|choice|switch 6|switch 5 -| -|switch|p2a: Heatran|Heatran, F, shiny|280/386 par -|-damage|p2a: Heatran|232/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|562/642 -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|turn|867 -|c|★Crime♥|he pressed the timer , cause he wants to go bed -|c|★Crime♥|lol -|c| gutu170599|there is a youtube video -|c| drowzee518|tg rd mana 6-0s both of these teams -|c| SingingTacos|i mean seriously -|c| drowzee518|ez -|c|★CHEF BOY4RDEEZNUTS|so do you -|c| LasagnaIsRectangle|night -|c| LasagnaIsRectangle|tell me who is the winner -|c| CriclesAreRound|this needs to go on youtube -|c| sancnea|does florges have any more wishes? -|c| QuagGod|singingtacos -|c|★Crime♥|yes -|c|★CHEF BOY4RDEEZNUTS|and youve been complaining about wanting a smoke this whole time -|c| QuagGod|just run offense -|c|★Crime♥|florges has a wish! -|c| LasagnaIsRectangle|:D -|c|★Crime♥|<333333333333333333 -|c| sancnea|how many? -|c| PI EddyChomp|Magikarp: __**I SWEAR TO GOD, WHEN I EVOLVE, I WILL KILL YOU ALL!!!**__ -|c| QuagGod|*well-built offense -|c| ZzamanN|1 -|choice|switch 6|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|868 -|c|★Crime♥|1 is enough for another hour -|c| QuagGod|and go from there -|c| Kuronachan|how long has the match been going on for; real time? -|c| SingingTacos|7 hours -|choice|move 3|move 1 -| -|move|p1a: I <3 Stall|Will-O-Wisp|p2a: Heatran -|-start|p2a: Heatran|ability: Flash Fire -|move|p2a: Heatran|Lava Plume|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|159/301 -| -|-heal|p2a: Heatran|304/386 par|[from] item: Leftovers -|turn|869 -|c| CriclesAreRound|just count the pp left....oh nvm -|c| drowzee518|7 hrs -|c| PI EddyChomp|9 Hours -|c| Kuronachan|jesus christ -|c| SingingTacos|mfw -|c| QuagGod|>7 hours -|c| LasagnaIsRectangle|jesus -|c| lordkaelros|1 more lave plume bois -|c| QuagGod|who has the time -|c| SingingTacos|is this where -|c|★CHEF BOY4RDEEZNUTS|one more plume bro -|choice|switch 6|move 2 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|cant|p2a: Heatran|par -| -|-heal|p2a: Heatran|328/386 par|[from] item: Leftovers -|turn|870 -|c|★CHEF BOY4RDEEZNUTS|use it -|c| QuagGod|for that -|c|★CHEF BOY4RDEEZNUTS|i dare you -|c| QuagGod|jesus -|c|★Crime♥|you are lucky you had no burn -|c|★Crime♥|hey CHEF -|c|★Crime♥|are you over ur sleep? -|c|★Crime♥|lol -|c| charizard8888|/me gives an Everstone to PI EddyChomp -|c| SingingTacos|this is cancer af -|c| PI EddyChomp|Lol -|c| SingingTacos|im out -|c| anthonygmars|I'MA GO SLEEP -|c| Kuronachan|the players just have the cries of chansey switching in etched into their mind by now -|c| lordkaelros|wait, has clef been out yet? -|choice|move 3|move 2 -| -|move|p1a: Fatty|Wish|p1a: Fatty -|move|p2a: Heatran|Roar|p1a: Fatty -|drag|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-heal|p2a: Heatran|352/386 par|[from] item: Leftovers -|turn|871 -|c| Kuronachan|its all they'll hear from now on -|c| anthonygmars|I HOPE YOU ALL DIE -|c| LifeisDANK|WOOP -|c| Kuronachan|that shitty 8-bit roar -|c| LifeisDANK|ILY anthony -|c| hey i'm pikachu|spoiler: use healing wish chanse -|c| PI EddyChomp|/me throws Everstone and Replaces with 10 Rare Candy's -|c| anthonygmars|<3 -|c| LifeisDANK|;) -|c| QuagGod|whens the 1st blood -|c| QuagGod|:( -|c| CriclesAreRound|i went on a vaccation to france and this battle is still going on.... -|c| Gaussfield|we all die though -|choice|switch 5|switch 6 -| -|switch|p1a: Fatty|Chansey, F|562/642 -|-end|p2a: Heatran|ability: Flash Fire|[silent] -|switch|p2a: Skarmory|Skarmory, F|264/334 -|-damage|p2a: Skarmory|223/334|[from] Stealth Rock -| -|-heal|p1a: Fatty|642/642|[from] move: Wish|[wisher] Fatty -|turn|872 -|c| hey i'm pikachu|quaggod u staller -|c| PI EddyChomp|/me Evolves Magikarp -|c| hey i'm pikachu|u can't ignore others dancing -|c| lordkaelros|1 more defog -|c| anthonygmars|wait what move is this? -|choice|switch 3|move 4 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|move|p2a: Skarmory|Whirlwind|p1a: Redbull -|drag|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|turn|873 -|c| gutu170599|/me presses B button when it is evolving -|c| lordkaelros|go on, we know you want to -|c| QuagGod|k -|c| TheCanadianWifier|This game is stupid. Zarel, I hope you'll upload the replay by morning -|c| TheCanadianWifier|:P -|c| TheCanadianWifier|later guys -|c| LifeisDANK|il this game -|c| PI EddyChomp|/me spams A button -|c| LasagnaIsRectangle|just end it!! -|c| sancnea|man one of those days i wished ethers were allowed during competitive battling -|c| LifeisDANK|JUST DO IT -|c|★Crime♥|ok -|c|★Crime♥|im gonna smoke -|c| LifeisDANK|finish what you started -|c| Aluminion|lol -|c| hey i'm pikachu|w33d -|c|★Crime♥|i waited for 6 hours -|c| PI EddyChomp|/me 's Magikarp evolves -|c| LifeisDANK|smoke on your screen -|c| CriclesAreRound|1000 turns pls -|c| LifeisDANK|Dank it up -|c|★Crime♥|oke -|c| Funkytoucan|no pls -|c|★Crime♥|ill open a window -|c| BayFence|this battle is for chef -|c|★Crime♥|and play -|c| BayFence|crim cant win -|c| CoolSwag2015|lol -|choice|switch 2|move 4 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|move|p2a: Skarmory|Whirlwind|p1a: Redbull -|drag|p1a: I <3 Stall|Sableye-Mega, M|159/301 -| -|turn|874 -|c| QuagGod|breh -|c| gutu170599|/me takes the pokedex -|c| QuagGod|what strand u got -|c|★CHEF BOY4RDEEZNUTS|enjoy the lung cancer -|c| QuagGod|lol -|c|★Crime♥|why cant i win? :( -|c| LifeisDANK|toke n poke -|c| lordkaelros|Wait, so you had a smoke the whole time?? -|c| neXi|LOL -|c|★Crime♥|any guys who have hope for me? -|c| LifeisDANK|tokemon -|c|★Crime♥|<3 -|c| LasagnaIsRectangle|Just go a KO -|c| hey i'm pikachu|no -|c|★Crime♥|no one has hope for me -|c| LifeisDANK|I beleive in jew -|c| anthonygmars|i believe in you -|c|★Crime♥|im sad -|c| BayFence|because he is doing something u dont know and that will make u lose -|c| anthonygmars|<3 -|c| LifeisDANK|Crime you got this -|c| PI EddyChomp|This WILL be 900 and more turns -|c|★Crime♥|thank you LIfe <3 -|c|★Crime♥|lel -|c| CriclesAreRound|well i guess i'l return tommorow morning -|c| LifeisDANK|ayyy -|c|+SpaceBass|RIP timer incoming -|c| lordkaelros|tokemon -|c| lordkaelros|gotta smoke em all -|choice|move 4|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|875 -|c| Nortellaz|Convo time: Are y'all's favorite games strictly Pokemon? -|c| anthonygmars|Stallemon, the new game series -|c| LasagnaIsRectangle|no pkmn was fainted so peaceful -|c| gutu170599|Crime Chef please break the record -|c| sancnea|4 more recovers? -|c| CriclesAreRound|whats the record? -|c|★Crime♥|oke -|c|★Crime♥|lets get to 900 -|c| anthonygmars|911 -|c|★Crime♥|folks -|c| hater will hate|art thou scraty air balon -|c| Amber Torrey|Nah my favorite game is SUper mario world 2: Yoshi's Island -|c| gutu170599|6492 imo -|choice|switch 3|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|352/386 par -|-damage|p2a: Heatran|304/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|642/642 -| -|-heal|p2a: Heatran|328/386 par|[from] item: Leftovers -|turn|876 -|c| PI EddyChomp|Too bad Vegito isn't here -|c| Nortellaz|I love Yoshi's Island too <3 -|c| lordkaelros|1000 or gtfo -|c| anthonygmars|911 or gtfo -|c| CriclesAreRound|how do u even get to 6492? -|c| drowzee518|1025 -|c| The Suicoon|My favorite game franchise is Kingdom Hearts. -|c|★Crime♥|guys im gonna dc -|c| drowzee518|plz -|c| Rath111|alright -|c| LifeisDANK|I wanna be the very best -|c|★Crime♥|gg -|c| LasagnaIsRectangle|i believe in u guys -|c| Rath111|2 LoL matches and this match is still going -|c| sancnea|if i were to chose the winner now i would choose chef -|c| CriclesAreRound|noooooooooooooooo -|c| Amber Torrey|I love kingdom hearts to -|c| lordkaelros|My favourite game is Dark souls -|c| Asada Shino San|that was before endless battle clause -|c| Gaussfield|NOT LIKE THIS -|c| anthonygmars|like no one ever was -|c| gutu170599|this has taken how many hours? -|choice|switch 3|switch 6 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|877 -|c| hater will hate|the virgin loses this game -|c| drowzee518|turn timer off -|c| PI EddyChomp|NO DON'T FORFEIT -|c| lordkaelros|Followed by dishonored and witcher 3 -|c| Nortellaz|Favorite game's still Wind Waker though -|c| Amber Torrey|But dear god you need every system ever to play all of the kingdom hearts series -|c| Nortellaz|aka the only good Zelda -|c| Rath111|6 or 7 hours I believe -|choice|switch 5|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|328/386 par -|-damage|p2a: Heatran|280/386 par|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-heal|p2a: Heatran|304/386 par|[from] item: Leftovers -|turn|878 -|c| Nortellaz|Unless you count Okami ;) -|c| LifeisDANK|Sleep is for the WEAK lets keep it goin -|c| lordkaelros|u w0t m8 -|c| lordkaelros|link to the past was 8/8 -|c| The Suicoon|Not with the HD remixes! -|c| charizard8888|TURN OFF THE TIMER -|choice|switch 5|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Stealth Rock|p1a: I <3 Stall -|move|p1a: I <3 Stall|Stealth Rock|p2a: Heatran|[from]Magic Bounce -|-fail|p2a: Heatran -| -|-heal|p2a: Heatran|328/386 par|[from] item: Leftovers -|turn|879 -|c| anthonygmars|my grandma stalls better than you two. keep it going -|c| lordkaelros|minish cap was good too -|c|+SpaceBass|Nortellaz: aka the only good Zelda -|c| LifeisDANK|I thought majoras mask was interesting -|c|+SpaceBass|OoT says hi -|c| hey i'm pikachu|crap game -|c| i am having fun|oo 1 more rocks left -|c| Amber Torrey|Sorry but the HD remixes don't give you all the games -|choice|switch 2|switch 6 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|880 -|c| PI EddyChomp|I do not think it is on -|c| Nortellaz|Played it, didn't really like it :( -|c|+SpaceBass|Did you play the remake -|c| Amber Torrey|It gives you only the cutscenes from the handheld titles -|c|+SpaceBass|Or the original on n64 -|c| Nortellaz|I generally don't like the Zelda formula, which might explain why. -|c| Abgesang|lak sho -|choice|switch 4|switch 6 -| -|switch|p1a: TheMoreYouKnow|Jirachi|305/403 -|switch|p2a: Heatran|Heatran, F, shiny|328/386 par -|-damage|p2a: Heatran|280/386 par|[from] Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|330/403|[from] item: Leftovers -|-heal|p2a: Heatran|304/386 par|[from] item: Leftovers -|turn|881 -|c|+SpaceBass|Because original = best -|c| sancnea|how many roossts does the skarm have -|c| LasagnaIsRectangle|i wanna be the very best, like noone ever was, to catch was my real test , to train them is my cost -|c| Crean|//user zarel -|c| Nortellaz|Wind Waker shook things up considerably though -|c| The Suicoon|oh I didnt even know that was true -|choice|switch 2|switch 6 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|882 -|c| Rath111|will we hit 1000? -|c| The Suicoon|I bought a 3ds just for DDS :? -|c| LifeisDANK|someBODY once told me the world was gonna roll me -|c| The Suicoon|;/* -|c| PI EddyChomp|Probaly -|choice|switch 4|switch 3 -| -|switch|p2a: Cobalion|Cobalion|171/386 -|-damage|p2a: Cobalion|159/386|[from] Stealth Rock -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|turn|883 -|c| LifeisDANK|I aint the sharpest tool in the shed -|c| lordkaelros|If you come this far and don't hit 1000 -|c| RoyHasABigDiglett|This is making my laptop laggy -|c| lordkaelros|sham -|c| Amber Torrey|All-stars by smash mouth huh -|c| LasagnaIsRectangle|DDS?? -|c| Aluminion|1 rocks and 24 spins -|c| lordkaelros|*shame -|choice|switch 4|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|884 -|c| LifeisDANK|she was lookin kinda sumb wit her finger and her thumb -|c|★Crime♥|1 rock is enough for 24 spins -|c| Lottyloop|nothing is loading D: -|c|★Crime♥|:) -|c| LifeisDANK|in the shape of an L on her forhead -|c| Amber Torrey|it's DDD -|choice|switch 3|switch 3 -| -|switch|p2a: Cobalion|Cobalion|159/386 -|-damage|p2a: Cobalion|147/386|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|642/642 -| -|turn|885 -|c| Amber Torrey|Dream drop distance -|c| LifeisDANK|well the years start coming and they wont stop coming -|c| xX_SupaAfroMan_Xx|omg how many turns? -|c| Amber Torrey|not DDS -|c| PI EddyChomp|886 turns -|choice|switch 5|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|886 -|c| gutu170599|close combat? -|c| LifeisDANK|back to the start gonna kit the ground running -|choice|move 3|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|223/334 -|-damage|p2a: Skarmory|182/334|[from] Stealth Rock -|move|p1a: Annoying AF|Substitute|p1a: Annoying AF -|-start|p1a: Annoying AF|Substitute -|-damage|p1a: Annoying AF|264/352 tox -| -|-heal|p1a: Annoying AF|308/352 tox|[from] ability: Poison Heal -|turn|887 -|c| LifeisDANK|so much to do so much to see so whats wrong with taking the backstreets -|c| Swytch|this is what happens when you dont ban sableye -|c| Swytch|fuckin niggrs -|c| RoyHasABigDiglett|any 1 want my mixtape??? it's fire!! -|c| lordkaelros|Are those song lyrics? -|c| gutu170599|are you only switching? -|choice|switch 3|switch 5 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|888 -|c| LifeisDANK|I want your hot mixtape -|c| lordkaelros|I don't know any of them -|c| Aluminion|challenge (you must name a pokemon every turn until this game ends) -|c| LasagnaIsRectangle|what will happen if all PP is 0, they can only use sharpen -|c| LasagnaIsRectangle|:D -|c| Aluminion|who shall undertake this challenge -|c| Amber Torrey|Yes horrible missed up lyrics but yes lyrics -|choice|switch 4|switch 3 -| -|switch|p2a: Cobalion|Cobalion|147/386 -|-damage|p2a: Cobalion|135/386|[from] Stealth Rock -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|turn|889 -|c| Amber Torrey|It's All-stars by smash mouth -|c| Amber Torrey|messed* -|choice|move 4|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|336/394 tox -| -|-damage|p2a: Slowbro|312/394 tox|[from] psn -|turn|890 -|c| LifeisDANK|Lets do this pokemon challenge -|c|@Former Hope|Just randomly post this link in the suspect thread "This sums up why we shouldn't have sableye" and then drop mic -|c|★CHEF BOY4RDEEZNUTS|cob <3s those rocks -|c| lordkaelros|lol -|c| Rath111|23 more rapid spins -|c| hey i'm pikachu|xD -|c| hey i'm pikachu|xD -|c| hey i'm pikachu|xD -|c| Rath111|and nothing else -|c| Rath111|lmao -|c| Gaussfield|dk rap wen? -|c| sancnea|one question how is sableye out of calm minds? -|c|★Crime♥|lol -|c| hey i'm pikachu|florges -|c| sancnea|shouldnt it have swept by now? -|c| lordkaelros|890 turns does that -|c| Rath111|he has anxiety, that's why -|c|@Former Hope|Probably because it's had to wait to long sancnea -|c|★CHEF BOY4RDEEZNUTS|tran bro -|c|@Former Hope|That would make anyone not calm -|choice|switch 5|switch 3 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Cobalion|Cobalion|135/386 -|-damage|p2a: Cobalion|123/386|[from] Stealth Rock -| -|turn|891 -|c| hey i'm pikachu|forces it out -|c|★CHEF BOY4RDEEZNUTS|and florgs -|c| sancnea|i mean forced out 24 times? -|c| hey i'm pikachu|stall is such a good playstyle -|choice|switch 4|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|892 -|c| hey i'm pikachu|it promotes global peace -|c| Amber Torrey|because sableye would set up calm minds -|c| xX_SupaAfroMan_Xx|i cant see the battle it just says seeking... on my screen -|c| Amber Torrey|then crime would send out chansey -|c| sancnea|pretty balanced u knw what im sayin? -|c| Amber Torrey|who can't be hit -|c| Gaussfield|TURN 900 HYPE -|choice|switch 5|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|893 -|c| charizard8888|It's Loading xX_SupaAfroMan_Xx -|c| Kuronachan|TURN 900 HYPE -|c| hey i'm pikachu|only 7 more turns -|c| PI EddyChomp|IT WILL HIT 900!!!!! YAY -|c| charizard8888|It will eventually load -|c| gorry oak|use surf -|c| hey i'm pikachu|7777 -|c| LifeisDANK|HYPE -|c| PI EddyChomp|HIT 900 HYPE -|c| Amber Torrey|sableyes moveset is recover,calm mind, will-o-wisp, shadow ball -|c| xX_SupaAfroMan_Xx|ok thnx charizard8888 -|c| LifeisDANK|https://www.youtube.com/watch?v=u9ymUX1fJLw SET THE MOOD -|c| Amber Torrey|can't do jack to chansey -|c| PI EddyChomp|**MAKE IT 950 TURNS HYPE!!!** -|c| CoolSwag2015|**Turn 900 hype n.n** -|c| Swytch|both players in this game suck -|choice|move 4|switch 3 -| -|switch|p2a: Cobalion|Cobalion|123/386 -|-damage|p2a: Cobalion|111/386|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-crit|p2a: Cobalion -|-damage|p2a: Cobalion|106/386 -| -|turn|894 -|c| Kuronachan|ultimately I'm for turn 1024 hype -|c| Amber Torrey|I'm not a religious man -|c| Rath111|oh shit -|c| Rath111|crit for 0% -|c| Kuronachan|900 is a great milestone -|c|★Crime♥|0% crit -|c| Rath111|OP -|c| CoolSwag2015|looooooool -|c| CriclesAreRound|turn 900 hype! -|c| Gaussfield|**test** -|c|★Crime♥|op -|c| CoolSwag2015|0% -|c| i am having fun|damage -|c| Amber Torrey|But if hell exists can't imagine it's much different then this -|c| Gaussfield|oh -|c| lordkaelros|lmao -|c| PI EddyChomp|Lol -|c| LifeisDANK|AYYYYYYYYYY -|c| CoolSwag2015|tentacruel -|c| Gaussfield|Z E R O D A M A G E -|c| CoolSwag2015|is op -|c| PI EddyChomp|0% Crit -|c| Abgesang|sigh both teams are so bad and there still isn't an end -|choice|switch 6|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Redbull|Clefable, M|393/393 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|895 -|c|+Frizy|its already over lol -|c| PI EddyChomp|Look at how many turns -|choice|move 4|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|304/386 par -|-damage|p2a: Heatran|256/386 par|[from] Stealth Rock -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -| -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|896 -|c|+Frizy|crime cant win -|c|★Crime♥|=[ -|c| Amber Torrey|neither can win -|c|★Crime♥|im crying -|c| Amber Torrey|or lose -|c| LifeisDANK|Crime i bee leaf in u -|c| Kuronachan|crime never pays........ -|c| PI EddyChomp|;) -|c|@Former Hope|It's Frizy :o -|c| lordkaelros|The god comes out -|c|★Crime♥|thanks <3 -|c| jepler|this is your chance to sweep -|c| hey i'm pikachu|crime will not stand a chance -|c| RoyHasABigDiglett|this is 2 dank -|c| Amber Torrey|each team has endless stall -|c| hey i'm pikachu|against peace -|c| PI EddyChomp|P;) -|c| LifeisDANK|not DANK enough -|c| CoolSwag2015|Frizy -|c| CoolSwag2015|Crime can win! -|c| CoolSwag2015|~~the other one can forfeit~~ -|c| Gaussfield|don't give up on hoop -|c| Rath111|oh shit -|c| lordkaelros|the clefagod begins it's reign of blood -|c| Rath111|will this be it? -|c| LifeisDANK|,':) -|choice|switch 5|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Taunt|p1a: I <3 Stall -|move|p1a: I <3 Stall|Taunt|p2a: Heatran|[from]Magic Bounce -|-start|p2a: Heatran|move: Taunt -| -|-heal|p2a: Heatran|304/386 par|[from] item: Leftovers -|turn|897 -|c| lordkaelros|I guess not -|c| Kuronachan|IT'S KILL OR BE KILLED, JACK -|c| Gaussfield|WITHDREW -|c| gutu170599|more 5500 turns for record.... go..... -|c| lordkaelros|NO MORE TAUNT BOIS -|c| Aluminion|rekt -|c| Eon_Theory|what is this -|c| Rath111|NO MORE TAUNTS -|choice|switch 5|switch 6 -| -|switch|p1a: Redbull|Clefable, M|393/393 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|898 -|c| Aluminion|taunt is f*cking useless anyway -|c| Kuronachan|YOU CAN'T FIGHT NATURE -|c| gutu170599|:^) -|c| lordkaelros|All hail clefagod -|choice|switch 5|move 3 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Slowbro|Toxic|p1a: I <3 Stall -|move|p1a: I <3 Stall|Toxic|p2a: Slowbro|[from]Magic Bounce|[miss] -|-miss|p1a: I <3 Stall|p2a: Slowbro -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|899 -|c| hey i'm pikachu|**2 more turns** -|c| hey i'm pikachu|1 more -|c| LifeisDANK|HYPE -|c| LifeisDANK|AY -|c| LifeisDANK|YEE -|c| Gaussfield|**TURN 900 HYPE** -|c| BayFence|good predict -|choice|switch 4|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|304/386 par -|-damage|p2a: Heatran|256/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|642/642 -| -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|900 -|c| LifeisDANK|CELEBRATE GUYS https://www.youtube.com/watch?v=u9ymUX1fJLw -|c| CoolSwag2015|**Turn 900 :D** -|c| Kuronachan|TURN 900 -|c| lordkaelros|WOOOHOOO -|c| PI EddyChomp|900 TURNS!!!!! THE GOAL IS REACHED!!!!!!! **YES THIS HYPE!!!** -|c| Gaussfield|ayyy -|c| charizard8888|**900** -|c|★Crime♥|900 -|c| No 1 Machop Fan|really... -|c| Kuronachan|ITS HERE -|c| lordkaelros|1024 hype bois -|c| Aluminion|go for dem lava plume burns -|c| RoyHasABigDiglett|(gets the popcorn) -|c| Dfmetal|is 1000 possible ? -|c| gutu170599|yay 900 -|c| Kuronachan|CEEEEEEEEEELEBRATE YOUR TIME COME ON -|c| CoolSwag2015|1000 now imo :^) -|c| No 1 Machop Fan|I came here expecting to see a 150-turn FINISHED battle! -|c| Rath111|yes -|c| CriclesAreRound|900! -|c| drowzee518|1025 -|c| Rath111|i'm calling the 1000 -|c| gutu170599|1000 hype -|c| drowzee518|lezgo -|c| LifeisDANK|AYyy -|c| LifeisDANK|yyy -|c| LifeisDANK|yy -|c| LifeisDANK|y -|c| CoolSwag2015|**1000 hype** -|c| PI EddyChomp|__** Is 950 possible??**__ -|c| Amber Torrey|you know with no more taunts clefable could setup and sweep i think -|c| sancnea|and capt. 'merica has been revived (againt) -|c| RoyHasABigDiglett|Popcorn Any1? -|c|★CHEF BOY4RDEEZNUTS|DEEZ NUTS FOR PRESIDENT EVERYBODY -|c| Rath111|heatran has roar though -|c|@Former Hope|Amber Torrey, there's also phasing -|c| lordkaelros|Unless it isn't magic guard -|c| charizard8888|NO ADVERTISING HERE -|c| CoolSwag2015|lol -|c| drowzee518|5 roars -|c|★CHEF BOY4RDEEZNUTS|DEEZ NUTS WILL MAKE AMERICA GREAT AGAIN -|choice|switch 4|switch 6 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|901 -|c| hey i'm pikachu|**over 90000000!!!!!!!!** -|c| Aluminion|youtube.com/channel/noadvertising -|c|+Frizy|clef doesnt need to sweep -|c| Eon_Theory|Istill cant see the game -|c| Eon_Theory|ayyy -|c| lordkaelros|And a fuckton of whirlwinds -|c|+Frizy|chef just keeps switching -|c| Eon_Theory|holy crap -|c| Gaussfield|7 asses -|c| Eon_Theory|901 turns -|c| Eon_Theory|6 mons -|choice|switch 4|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|280/386 par -|-damage|p2a: Heatran|232/386 par|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|642/642 -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|turn|902 -|c| gutu170599|how many users are here currently? -|c| Kuronachan|the state of the pokemon meta -|c| GROUDONNNN|too many -|c| Vicky★the✡Shitlord|a whole fuckin lot -|c| charizard8888|80 GGs for me -|c| CriclesAreRound|its over 900! -|c| Gaussfield|not enough -|c| sancnea|a very nice question gutu -|c| Kuronachan|does crime's skarm -|choice|switch 6|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: Redbull|Clefable, M|393/393 -| -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|903 -|c| Kuronachan|not have defog -|c|★Crime♥|lol -|c| Wasim007|they are not even trying to win -|c| sancnea|yes!!! roar success -|c| Vicky★the✡Shitlord|there -|c| Wasim007|they are just stalling for moves -|c| hey i'm pikachu|spoiler: press x -|c| Vicky★the✡Shitlord|is no wincon -|c| Vicky★the✡Shitlord|of course theyre not trying to win -|c| sancnea|lol -|c| Gaussfield|[x] -|choice|switch 5|switch 6 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|904 -|c| Kuronachan|use defog to prolong game plz........ -|c| LasagnaIsRectangle|any pokemon fainted yet?? -|c| Gaussfield|dude what -|c| Gaussfield|[test] -|c| Kuronachan|no pokemon are dead -|c| Gaussfield|amazing -|c| RoyHasABigDiglett|DANK!!!!!!!!! -|c| LifeisDANK|YE -|choice|switch 6|switch 6 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Heatran|Heatran, F, shiny|280/386 par -|-damage|p2a: Heatran|232/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|turn|905 -|c| LifeisDANK|BRUH -|c| gutu170599|ok 58 users currently here -|c| Vicky★the✡Shitlord|friendly reminder to brush ur teeth -|c| CoolSwag2015|lol -|c| charizard8888|how did you count that gutu170599 -|choice|switch 2|switch 6 -| -|switch|p1a: TheMoreYouKnow|Jirachi|330/403 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|355/403|[from] item: Leftovers -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|906 -|c|★Crime♥|lol -|c| LifeisDANK|Friendly reminder to TURN UP -|c| Apathos|this isnt even loading properly -|c| Kyorem|we need defog -|c| Apathos|i cant see the pokemon -|c| jepler|this is a once in a lifetime oppurtunity -|c| Vicky★the✡Shitlord|apathos give it a minute -|c| Vicky★the✡Shitlord|youre loading 906 turns -|c| lordkaelros|or 5 -|choice|switch 3|move 2 -| -|switch|p1a: Annoying AF|Gliscor, M|308/352 tox -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|907 -|c| Kuronachan|scald 2win -|choice|switch 2|switch 3 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Cobalion|Cobalion|106/386 -|-damage|p2a: Cobalion|94/386|[from] Stealth Rock -| -|turn|908 -|c| gutu170599|i did ctrl+f and checked the people joined - the people left charizard8888 -|c| Kuronachan|oh my god -|c|★Crime♥|910 -|c| Kuronachan|is cobalion -|c| lordkaelros|coba getting whittled -|c| Kuronachan|going to be THE FIRST SACRIFICE -|c|★Crime♥|no -|c| charizard8888|Thanks gutu170599 -|c|★Crime♥|i have a suprise for you guys later -|c| LifeisDANK|WOop -|choice|switch 5|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Redbull|Clefable, M|393/393 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|909 -|c| Nortellaz|He's gonna wish him -|c| lordkaelros|woah -|c| Kyorem|__I love surprises__ -|c| Rath111|lmao -|c|★CHEF BOY4RDEEZNUTS|dicksalt -|c| Gaussfield|a surprise this late into the game? -|c| Gaussfield|amazing -|c|★Crime♥|haha nOrtella'z -|c| BayFence|the surprise is the lose? -|c| LifeisDANK|I love all the surprises -|c| Daze-Senpai|Ayy -|c| Rath111|omg chansey -|c| Rath111|has wishes -|c|+Frizy|whats with some of these sets lol -|c| Rath111|left -|choice|move 4|move 3 -| -|move|p1a: Redbull|Calm Mind|p1a: Redbull -|-boost|p1a: Redbull|spa|1 -|-boost|p1a: Redbull|spd|1 -|move|p2a: Slowbro|Toxic|p1a: Redbull -|-status|p1a: Redbull|tox -| -|-damage|p1a: Redbull|369/393 tox|[from] psn -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|910 -|c| RoyHasABigDiglett|wait -|c| gutu170599|now 38 -|c| lordkaelros|kek -|c| LifeisDANK|AHhh -|c| Daze-Senpai|The window is still saying "Seeking" -|c|★Crime♥|rekt -|c| Amber Torrey|Randomly Heatran uses explosion while chef switches to sableye -|c| LifeisDANK|GG -|c|★Crime♥|go to bed CHEF -|c| lordkaelros|R E K T -|c| LifeisDANK|its ova -|c| Rath111|NO DON'T -|c| Rath111|KEEP PLAYING -|c|★Crime♥|is it -|c|★Crime♥|REKT or SHREKT -|c| PI EddyChomp|I have hardly seen Jirachi battle yet. -|c| Gaussfield|D E S T R O Y E D -|c| Gaussfield|is the word -|choice|move 1|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|256/386 par -|-damage|p2a: Heatran|208/386 par|[from] Stealth Rock -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|174/386 par -| -|-heal|p1a: Redbull|393/393 tox|[from] item: Leftovers -|-heal|p2a: Heatran|198/386 par|[from] item: Leftovers -|-damage|p1a: Redbull|345/393 tox|[from] psn -|turn|911 -|c| lordkaelros|Y u no mguard :( -|c| lordkaelros|u fucked na0 -|c|★Crime♥|nice damage -|c|★Crime♥|XD -|c| Kuronachan|game of roar -|c| LifeisDANK|annihilated -|c| RoyHasABigDiglett|مدح الرب -|c| TheCanadianWifier|omg ITS HAPPENING -|c| TheCanadianWifier|pls win -|c| Rath111|omg -|c| No 1 Machop Fan|911 -|c| TheCanadianWifier|with this -|c| Rath111|911 -|c| No 1 Machop Fan|/me is not American -|c| LifeisDANK|lel -|c| Eon_Theory|911 -|c| Rath111|never forget -|c| RoyHasABigDiglett|911 -|choice|move 3|move 2 -| -|move|p1a: Redbull|Wish|p1a: Redbull -|cant|p2a: Heatran|par -| -|-heal|p1a: Redbull|369/393 tox|[from] item: Leftovers -|-heal|p2a: Heatran|222/386 par|[from] item: Leftovers -|-damage|p1a: Redbull|297/393 tox|[from] psn -|turn|912 -|c| Eon_Theory|deez nuts will make this country great again -|c| Nortellaz|Holocaust -|c| gutu170599|911 -|c| Gaussfield|911 did bush -|c| LifeisDANK|911? you mean more like 420 -|c| PI EddyChomp|910!!!! -|c| Nortellaz|Never forget -|c|★Crime♥|all planned -|c| RoyHasABigDiglett|مدح الرب -|c| StAlRuth|loaded on 9/11 what is this -|c| gutu170599|912 -|choice|switch 4|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Heatran|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Heatran|[from]Magic Bounce -|drag|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|913 -|c| TheCanadianWifier|finally loaded for me, lol -|c| Eon_Theory|is this a real battle? -|c| Kuronachan|is the american police telephone number 911 because of 9/11 -|c| JacobWorld|I can't see anything -|c| lordkaelros|lmao -|c| Amber Torrey|Wait why would your clefable not be magic guard on a stall team? -|c|★Crime♥|perfect -|c|★Crime♥|back to slowbro -|c| Eon_Theory|or is this just a challenge? -|c| Gaussfield|this is a surreal battle -|c| lordkaelros|I don't know -|c| LifeisDANK|Its ludacris -|c| i am having fun|ladder Eon_Theory -|c| lordkaelros|Why u no mguard bru -|c| LifeisDANK|its eminem -|c| Eon_Theory|oh my godi -|c| Kuronachan|because -|c| Kuronachan|cute charm -|c| Eon_Theory|is this a real ladder battle -|c|★Crime♥|yes -|c| Kuronachan|clefable just wants to be pretty :( -|c| Gaussfield|yep -|c|+Frizy|unaware clef is fine -|c| CriclesAreRound|this is has become bigger than many showdown rooms -|c| Eon_Theory|holy crap -|c|★Crime♥|this is a real OU game random.. -|c| LifeisDANK|gotta be a cutie in a battle -|c| i am having fun|it says rated battle at the very top -|c|★Crime♥|you guys can see it at the end -|c| i am having fun|that means its ladder -|c|+Frizy|that set is horrible tho.. -|c| Eon_Theory|oh true -|c| Eon_Theory|lmao -|c| Eon_Theory|your clef set is bad -|c| JacobWorld|spoiler: -|c| Eon_Theory|and you should feel bad -|c| RoyHasABigDiglett|Any1 here have Drakeitis? -|choice|switch 6|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|914 -|c| Eon_Theory|:< -|c| hey i'm pikachu|____ -|c|★Crime♥|gosh 10 slack off left -|c| Eon_Theory|lmfao -|c| TheCanadianWifier|anyone here play mk8? :o -|c| Eon_Theory|only 10? -|c| hey i'm pikachu|____________________ -|c| Gaussfield|spoiler: -|c| CoolSwag2015|rip lol -|c| PI EddyChomp|You should call Tentacreul Jellybruu -|choice|move 4|switch 2 -| -|switch|p2a: Florges|Florges, F|207/360 -|-damage|p2a: Florges|162/360|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Florges -|-damage|p2a: Florges|147/360 -| -|turn|915 -|c| Kuronachan|back in my day if you had a psychic type against a poison type you won -|c| Nortellaz|chef, at this point I would go for turn 1024 so that neither of you wins -|c| QuagGod|so i come back from making hot cocoa after my internet gave in -|c| Kuronachan|this is fucking bullshit -|c| lordkaelros|110 turns left -|c|★CHEF BOY4RDEEZNUTS|HE COMES THE WISH -|c| QuagGod|and still this is going on -|c| sancnea|im so addicted right now -|c| lordkaelros|we can do it -|c|★CHEF BOY4RDEEZNUTS|FUCK ME -|c| LifeisDANK|IF YOU WISH UPON A STARrr. -|c| sancnea|cant move onto nother gamea -|c| QuagGod|im still loading too kek -|c|★Crime♥|i think its early for a wish ^^ -|c|+Frizy|does it actually end at 1024 lol -|c| QuagGod|o shit its finished -|choice|switch 4|switch 2 -| -|switch|p1a: Redbull|Clefable, M|297/393 tox -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: Redbull|321/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|297/393 tox|[from] psn -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|916 -|c| Eon_Theory|this is like twitch plays pokemon -|c| Eon_Theory|all over again -|c| StAlRuth|it's the last wish -|c| StAlRuth|aww rip -|c| PI EddyChomp|Florges and Cobalion have too be sacrificed -_- -|c|★Crime♥|TOO EARLY FOR A WISH GUYS -|c|★Crime♥|the game didnt even start yet -|c| PI EddyChomp|Lol -|c|★Crime♥|lol -|c| StAlRuth|>turn 916 -|c| PI EddyChomp|LOL -|c| QuagGod|lol -|c| lordkaelros|lmao -|c| LifeisDANK|Lets see to the edge of this earth brethren, is this 1042 a legend or a fact -|c|★Crime♥|kil -|c|★Crime♥|lol -|c| StAlRuth|jfc lmao -|c| lordkaelros|Typical stall player -|c| Kuronachan|I wish this cancer never happened -|c| Amber Torrey|Nah Twitch plays pokemon had way more progress then this bs -|c| StAlRuth|bring it to 2015 -|c| TheCanadianWifier|Crime, CHEF... Enjoy this. Really. You'll never be this interesting or popular for a loong time, and possible never :P -|c|@Former Hope|I'm pretty sure when you run out of bullets marks the end of a battle. -|c| JacobWorld|this is going to be history -|c| Nortellaz|In other news: Last Smash direct coming guys! Fingers crossed for Geno (cries inside). -|c| StAlRuth|what are we banning after this bs? -|c| TheCanadianWifier|you have 60 + people watching your every move -|c|★Crime♥|yes im happy about it -|c| No 1 Machop Fan|this is why stall is bad in OU -|c|★Crime♥|i admit it -|c|★CHEF BOY4RDEEZNUTS|means nothing to me canada -|c| Kuronachan|fuck geno -|c| Rath111|you have 40 seconds left crime -|c| No 1 Machop Fan|if two OU stall teams meet, this happens -|c| LifeisDANK|When youre outta bullets ya use your fists -|c| Kuronachan|we need a weapon to surpass metal gear -|c| StAlRuth|this is why we play vgc no 1 machop fan -|c| Amber Torrey|Popular for the wrong reasons -|c| Nortellaz|Why fuck Geno? :( -|c| No 1 Machop Fan|exactly :p -|choice|move 3|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|222/386 par -|-damage|p2a: Heatran|174/386 par|[from] Stealth Rock -|move|p1a: Redbull|Wish|p1a: Redbull -| -|-heal|p1a: Redbull|321/393 tox|[from] item: Leftovers -|-heal|p2a: Heatran|198/386 par|[from] item: Leftovers -|-damage|p1a: Redbull|273/393 tox|[from] psn -|turn|917 -|c| Nortellaz|That's kinda grodd -|c| Nortellaz|*gross -|c| gutu170599|bye guys make it 5000....... -|c|★Crime♥|lol -|c| LifeisDANK|fuck geno ,':) -|c| No 1 Machop Fan|at least VGC16 has the decency to use 4 Pokémon 2 at a time and to be hyper-offensive -|choice|move 1|move 3 -| -|move|p1a: Redbull|Moonblast|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|176/386 par -|move|p2a: Heatran|Stealth Rock|p1a: Redbull -|-sidestart|p1: CHEF BOY4RDEEZNUTS|move: Stealth Rock -| -|-heal|p1a: Redbull|393/393 tox|[from] move: Wish|[wisher] Redbull -|-heal|p2a: Heatran|200/386 par|[from] item: Leftovers -|-damage|p1a: Redbull|321/393 tox|[from] psn -|turn|918 -|c| Amber Torrey|wait Geno from one-punch man? -|c|★Crime♥|rocks time -|c| lordkaelros|OOOO -|c| Gaussfield|dat timer -|c| LifeisDANK|THE ROCKS -|c| Eon_Theory|genos -|c| lordkaelros|No more rocks -|c|★Crime♥|DA ROCKS -|c|★Crime♥|lol -|c| gutu170599|Crime CHEF try 6493.... -|choice|switch 6|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|-damage|p1a: I <3 Stall|264/301|[from] Stealth Rock -|move|p2a: Heatran|Roar|p1a: I <3 Stall -|move|p1a: I <3 Stall|Roar|p2a: Heatran|[from]Magic Bounce -|drag|p2a: Cobalion|Cobalion|94/386 -|-damage|p2a: Cobalion|82/386|[from] Stealth Rock -| -|turn|919 -|c| Eon_Theory|THE ROCKS ARE UP -|c| Eon_Theory|GG -|c| TheCanadianWifier|Don't time out ;) -|c| Kuronachan|at least any decent format has the decency to not have mega rayray -|c| Nortellaz|You idiots, Tenta has Spin. Doesn't matter. -|c| No 1 Machop Fan|8192? :p -|c| JacobWorld|lol -|c| sancnea|introducing the switch clause, inspired due to the unhealthy obesessive nature of the unreal number of turns in a single ladder battle -|c| Eon_Theory|damn it -|choice|switch 2|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|182/334 -|-damage|p2a: Skarmory|141/334|[from] Stealth Rock -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|-damage|p1a: Annoying AF|308/352 tox|[from] Stealth Rock -| -|-heal|p1a: Annoying AF|352/352 tox|[from] ability: Poison Heal -|turn|920 -|c| QuagGod|holy fuck -|c| QuagGod|why is timer still on -|c| QuagGod|turn it off zzz -|c|★CHEF BOY4RDEEZNUTS|Still itching for that smoke Crime? -|c|★Crime♥|yes lol -|c| PI EddyChomp|920!! -|c| StAlRuth|introducing a ban on pokemon with a bulk to attack ratio > some number -|c| TheCanadianWifier|8192 is the MC value for diamond -|c|★Crime♥|i still didnt smoke -|c| No 1 Machop Fan|hmm... -|c| LifeisDANK|this is amazing -|c| lordkaelros|Let the psychologicalwarfare begin -|c| Enzonana|Omg -|choice|switch 3|switch 6 -| -|switch|p1a: TheMoreYouKnow|Jirachi|355/403 -|-damage|p1a: TheMoreYouKnow|330/403|[from] Stealth Rock -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|355/403|[from] item: Leftovers -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|921 -|c| Nortellaz|Smoking is bad for you. I'm glad I never picked up the habit. -|c|★Crime♥|im gonna lose -|c| Gaussfield|this right here -|c|★CHEF BOY4RDEEZNUTS|agreed nort -|c|+SpaceBass|★CHEF BOY4RDEEZNUTS: Still itching for that smoke Crime? -|c| Gaussfield|is the next level -|c|+SpaceBass|Brutal stall tactics -|c| Eon_Theory|CHEF BOY4RDEEZNUTS is a dumb bumb -|c| Enzonana|920 turns -|c| LifeisDANK|crime i beeleeve in u -|c| Enzonana|6vs6 -|c| Enzonana|loool -|c| Eon_Theory|psychological warfare -|c| BayFence|enzo fuera de aqui -|choice|switch 4|switch 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|-damage|p1a: U Jelly Bruh?|318/363|[from] Stealth Rock -|switch|p2a: Chansey|Chansey, F|535/642 -|-damage|p2a: Chansey|455/642|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|340/363|[from] item: Black Sludge -|turn|922 -|c| lordkaelros|You guys should have taken a break at turn 420 -|c| TheCanadianWifier|just get'ter to 1000 please :] -|c|★CHEF BOY4RDEEZNUTS|paying $$$ for cancer -|c| lordkaelros|And hit a blunt -|c| Enzonana|no mamaes bay -|c| Rath111|NO WISHES -|c|★CHEF BOY4RDEEZNUTS|smoking is dumb -|c| StAlRuth|come on CHEF BOY4RDEEZNUTS, let crime have a smoke break lmao -|c| StAlRuth|:^) -|choice|move 4|move 1 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Chansey -|-damage|p2a: Chansey|440/642 -|-sideend|p1: CHEF BOY4RDEEZNUTS|Stealth Rock|[from] move: Rapid Spin|[of] p1a: U Jelly Bruh? -|move|p2a: Chansey|Seismic Toss|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|240/363 -| -|-heal|p1a: U Jelly Bruh?|262/363|[from] item: Black Sludge -|turn|923 -|c| Nortellaz|Not only that, non-smokers have to breathe in the shitty secondhand smoke -|c| No 1 Machop Fan|^ -|choice|switch 2|switch 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|924 -|c| Kuronachan|ONLY 100 TURNS TO GO BOYS -|c| No 1 Machop Fan|spare a thought for the children of smokers -|c| Nortellaz|Pretty fucking ridiculous. -|c| No 1 Machop Fan|when I was young I had to put up with it -|c| Kyorem|I sell cigarettes at my work -|c| Kuronachan|everyone is leaving -|c| No 1 Machop Fan|thankfully my mother grew up and quit -|c| Nortellaz|Same here, my dad was a chain smoker :( -|c| LifeisDANK|this shit is bananas -|choice|switch 5|switch 5 -| -|switch|p2a: Cobalion|Cobalion|82/386 -|-damage|p2a: Cobalion|70/386|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|642/642 -| -|turn|925 -|c| LifeisDANK|b a n a n a s -|choice|switch 5|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|926 -|c| lordkaelros|coba getting whittled -|c| Nortellaz|But he's Korean, so he has this super Asian genes that prevent him from getting lung cancer -|c| lordkaelros|time to bring out the wish -|c| Dfmetal|★Crime♥: im not good at stall yet ;3 -|c| Eon_Theory|coba -|c| Amber Torrey|My parents grandparents and aunts all smokes about 2 packs a day -|c| Dfmetal|Turn 3 -|c| Eon_Theory|pls dont die -|c| Amber Torrey|not a single one got cancer -|c|★Crime♥|lol -|c| StAlRuth|and I thought my 45 min game at the burwood PC was stally -|c| No 1 Machop Fan|smoking is still bad -|c| No 1 Machop Fan|it's gross -|c| gorry oak|dankthony mangtano -|c| QuagGod|tobacco is bad for u -|c| BaconChest|test -|c|★Crime♥|i prefer to smoke than eat a piece of pork meat -|c| LifeisDANK|dank -|c| Nortellaz|Genetics is probably as significant as a factor as to whether you'd get cancer -|c| RoyHasABigDiglett|dank -|c|★CHEF BOY4RDEEZNUTS|why spend money on cigs when you can buy tacos? -|c| QuagGod|smoke cannabis instead, its a lot cleaner -|c| LifeisDANK|AY -|c| GiraGoomy|timer bois -|c| Eon_Theory|are you guys even trying to win at this point? -|c| QuagGod|:^) -|c|@Former Hope|Mega evolve Slowbro on turn 1000 -|c| lordkaelros|Cannabis life -|c| Nortellaz|That's cool, I'm trying to be vegetarian too -|c| StAlRuth|they're really just trying to not lose -|choice|switch 5|switch 5 -| -|switch|p2a: Cobalion|Cobalion|70/386 -|-damage|p2a: Cobalion|58/386|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|642/642 -| -|turn|927 -|c| drowzee518|pot has like 5x the risk for cancer tho -|c| JacobWorld|how long has this battle gone on for -|c| QuagGod|not even truw -|c| QuagGod|*truw -|c| lordkaelros|uw0tm8 -|c|★Crime♥|5 hours and 50 mins -|c| QuagGod|*true -|choice|switch 5|switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|928 -|c| drowzee518|yeah look it up -|c| Enzonana|LOL -|c| JacobWorld|really -|c| LifeisDANK|pot only gives you cancer if you inject it in your eyeballs ;) -|c| QuagGod|idk who told u that false info lol -|c| lordkaelros|kek -|choice|switch 5|move 2 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|929 -|c| Gaussfield|i'm gonna be gone for a while and i bet by the time i get back coballion will have more than 50% health -|c| zebba|jesus fucking christ -|c| Eon_Theory|slowbro had better mega evo on turn 1000 -|c| zebba|>singles -|c| drowzee518|just look it up -|choice|switch 3|switch 5 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|switch|p2a: Cobalion|Cobalion|58/386 -|-damage|p2a: Cobalion|46/386|[from] Stealth Rock -| -|turn|930 -|c| lordkaelros|We have looked it up -|c| QuagGod|i did extensive research on the cannabis plant -|c| lordkaelros|That's more bs than the vaccination haters -|c| Nortellaz|I looked it up. No real info. -|c| Durr00|HAS THIS BATTLE BEEN GOING FOR ALMOST 6 HOURS??? -|choice|switch 5|switch 2 -| -|switch|p2a: Florges|Florges, F|147/360 -|-damage|p2a: Florges|102/360|[from] Stealth Rock -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -| -|turn|931 -|c| Dfmetal|don't forgeit to save the replay :eh: -|c| LifeisDANK|wish time -|c| Nortellaz|That's like saying masturbation makes you blind. -|c| QuagGod|lmao -|c| CriclesAreRound|wtf -|c|★Crime♥|is it time for the wish? -|c| CriclesAreRound|rofl -|c|★Crime♥|or yet too early? -|c| Kyorem|lol -|c| LifeisDANK|But my eyes are fine! -|c| lordkaelros|Well, my eyesight IS pretty bad :p -|c| LifeisDANK|kek -|c| Eon_Theory|he has 1 wish -|c| Durr00|GUYS WTH? -|c| CriclesAreRound|dont wish yet -|c| Eon_Theory|better make it count -|c| LifeisDANK|wish -|c| Kyorem|wish now -|c| Enzonana|Wish to cobalion owo -|c| LifeisDANK|wish upon a star -|c| Nortellaz|You should probably wish, your Florges is gonna die pretty soon. -|choice|switch 6|move 4 -| -|switch|p1a: Redbull|Clefable, M|321/393 tox -|move|p2a: Florges|Wish|p2a: Florges -| -|-heal|p1a: Redbull|345/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|321/393 tox|[from] psn -|turn|932 -|c| hey i'm pikachu|spoiler: you could have played 100 battles in this game -|c| Nortellaz|ACTIVATION -|c| Kyorem|HERE IT COMES -|c| gorry oak|you've got about 400 turns left in this florges -|c| LifeisDANK|THERE IT IS -|c| Gaussfield|IT HAPPENED -|c| hey i'm pikachu|*with the time -|c| LifeisDANK|ATYTTTTTTTTT -|c| LifeisDANK|HYPE -|c| Kuronachan|iGNITION -|c|@Former Hope|>Hype over a wish -|c| LifeisDANK|VROOM -|choice|move 2|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|200/386 par -|-damage|p2a: Heatran|152/386 par|[from] Stealth Rock -|move|p1a: Redbull|Flamethrower|p2a: Heatran -|-start|p2a: Heatran|ability: Flash Fire -| -|-heal|p2a: Heatran|332/386 par|[from] move: Wish|[wisher] Florges -|-heal|p1a: Redbull|345/393 tox|[from] item: Leftovers -|-heal|p2a: Heatran|356/386 par|[from] item: Leftovers -|-damage|p1a: Redbull|297/393 tox|[from] psn -|turn|933 -|c|★Crime♥|ty -|c| lordkaelros|Wow -|c| Nortellaz|My wish is for world peace -|c| Kuronachan|OH -|c| Kuronachan|MY -|c| lordkaelros|The plays -|c| Kuronachan|GOD -|c| Gaussfield|dude -|c| lordkaelros|are so real -|c| Gaussfield|i -|c| QuagGod|wow -|c| charizard8888|Getting Weary -|c| LifeisDANK|THEM HARD READS -|c| Gaussfield|ohmygod -|c| QuagGod|what a lord -|c| QuagGod|lel -|choice|switch 3|switch 5 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|-end|p2a: Heatran|ability: Flash Fire|[silent] -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|934 -|c| Eon_Theory|spoiler: saitama-sama is my waifu -|c| QuagGod|lol -|c| BayFence|cobalio die and florges too -|c| gorry oak|i need it -|c| LifeisDANK|ive been here almost an hour -|c| StAlRuth|plz -|c| PI EddyChomp|This will go on forever............ -|choice|switch 5|move 3 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Slowbro|Toxic|p1a: Annoying AF -|-fail|p1a: Annoying AF|tox -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|935 -|c| StAlRuth|PLZ -|c| StAlRuth|ayyy -|c| Gaussfield|even if they do go down -|c| Gaussfield|slowbro is livin -|c| PI EddyChomp|I have been here 45 Minutes -|choice|switch 5|switch 5 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Heatran|Heatran, F, shiny|356/386 par -|-damage|p2a: Heatran|308/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|332/386 par|[from] item: Leftovers -|turn|936 -|c| Gaussfield|forever -|c| Pepeduce|Skarm die too -|c| StAlRuth|it continues -|choice|switch 2|switch 5 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|262/363 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|284/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|937 -|c| Nortellaz|Drinking game: Take a drink everytime someone switches! -|c| lordkaelros|This is the kind of game where you'd WANT to get paralyzed -|c| LifeisDANK|why not defog -|choice|switch 5|move 1 -| -|switch|p1a: Annoying AF|Gliscor, M|352/352 tox -|move|p2a: Slowbro|Scald|p1a: Annoying AF -|-supereffective|p1a: Annoying AF -|-crit|p1a: Annoying AF -|-damage|p1a: Annoying AF|8/352 tox -| -|-heal|p1a: Annoying AF|52/352 tox|[from] ability: Poison Heal -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|938 -|c| JacobWorld|yes nortellaz -|c|@Former Hope|Nortellaz and die of liver poisoning? -|c| LifeisDANK|AY -|c| QuagGod|good god i hope first blood is soon -|c| BayFence|he has just 1 defog -|c| hey i'm pikachu|he can just rocks -|c| lordkaelros|Lmao -|c| Gaussfield|HOOOOOOOOLY SHIT -|c| JacobWorld|hello -|c| hey i'm pikachu|again -|c| Kyorem|HOLY -|c| Rath111|LOL -|c| QuagGod|O FUCK -|c| GiraGoomy|SO CLOSE -|c| QuagGod|LOL -|c| CoolSwag2015|LOOOOOOOOL -|choice|move 4|switch 4 -| -|switch|p2a: Chansey|Chansey, F|440/642 -|-damage|p2a: Chansey|360/642|[from] Stealth Rock -|move|p1a: Annoying AF|Protect|p1a: Annoying AF -|-fail|p1a: Annoying AF -| -|-heal|p1a: Annoying AF|96/352 tox|[from] ability: Poison Heal -|turn|939 -|c| lordkaelros|SO CLOSE' -|c| Nortellaz|Mmm, good point. -|c| lordkaelros|SO FUCKING CLOSE -|c| Eon_Theory|OH MY -|c| No 1 Machop Fan|/me eats popcorn watching everyone react -|c| Eon_Theory|BIG PLAYS -|c| Eon_Theory|SO CLOSE -|c| Gaussfield|that wasn't even a crit -|choice|switch 6|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|940 -|c| Chaotic Midnight|.win Crime -|c| No 1 Machop Fan|*else -|c| Gaussfield|oh my god -|c| lordkaelros|21 tosses left -|choice|switch 2|move 1 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|move|p2a: Chansey|Seismic Toss|p1a: Fatty -|-damage|p1a: Fatty|542/642 -| -|turn|941 -|c| LifeisDANK|the plays -|c| lordkaelros|FATTY WARS -|c|★Crime♥|lol -|c| StAlRuth|and they say CHALK is an issue, we at least don't spend hours on a single game XD -|choice|switch 2|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|942 -|c| PI EddyChomp|...................................................................................................................................................................................... -|c| QuagGod|whar -|c| PI EddyChomp|............................................................. -|c| QuagGod|*what -|c|★Crime♥|time for a smoke -|c| JacobWorld|3 years later... -|c| QuagGod|a lord -|c| PI EddyChomp|........................................................................ -|c|★Crime♥|turn 1000 soon! -|c| StAlRuth|plz kill timer -|c| QuagGod|timer's still on tho -|c| LifeisDANK|100 more turns -|choice|switch 4|move 1 -| -|switch|p1a: TheMoreYouKnow|Jirachi|355/403 -|move|p2a: Chansey|Seismic Toss|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|255/403 -| -|-heal|p1a: TheMoreYouKnow|280/403|[from] item: Leftovers -|turn|943 -|c| QuagGod|turn that shit off fam -|c| CoolSwag2015|turn 950 hype -|c| QuagGod|:/ -|c| JacobWorld|turn 184730475 6-6 -|c| CoolSwag2015|!!! -|c| Kuronachan|chalk is an issue because it doesn't make you spend hours on a single game -|c| Kuronachan|this is art -|c| Kuronachan|this is legendary -|choice|move 2|move 1 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Chansey -|-status|p2a: Chansey|par -|move|p2a: Chansey|Seismic Toss|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|180/403 -| -|-heal|p1a: TheMoreYouKnow|205/403|[from] item: Leftovers -|turn|944 -|c| QuagGod|^ -|c|+Frizy|it really isnt -|c| lordkaelros|rachi can't do shit -|c| Nortellaz|I'm gonna have to leave. When I reach my gf's place and this battle still hasn't ended yet... -|c| BayFence|now cheef turn this battle i think u win -|c| Gaussfield|you went from "this is cancer" to "this is art" -|c| QuagGod|its got nothing on funbro tho *-* -|c|★Crime♥|lol -|choice|switch 6|move 1 -| -|switch|p1a: Annoying AF|Gliscor, M|96/352 tox -|move|p2a: Chansey|Seismic Toss|p1a: Annoying AF -|-damage|p1a: Annoying AF|0 fnt -|faint|p1a: Annoying AF -| -|c| LifeisDANK|This is a performance art, in the catergory or endurance -|c|+Frizy|chef trying hard to throw -|c| Nortellaz|BOOM! -|c| lordkaelros|GGGG -|c| qsns|are you -|c|★Crime♥|OMG -|c| CoolSwag2015|YES -|c| qsns|retarded -|c| Rath111|OMG -|c|★Crime♥|OMGGGGGGGGG -|c| JacobWorld|yay -|c| No 1 Machop Fan|YAY! SOMETHING! :p -|c| CoolSwag2015|YESSSSSSS -|c| lordkaelros|FIRST BLOOOD -|c| Rath111|OMG -|c| zebba|OH SHIT -|c| Gaussfield|FIRST BLOOD -|c| Rath111|OMG -|c| BaconChest|:D -|c| GiraGoomy|IT'S HAPPENED -|c|★Crime♥|WOHOOOOOOOOOOOo -|c| QuagGod|OMG -|c| lordkaelros|WOWOWOWOWOWOWOWOWW -|c|★Crime♥|FIRST BLOOD -|c| BaconChest|yessss -|c| JacobWorld|final -|c| LifeisDANK|HYPE -|c| CoolSwag2015|FINALLY LOL -|c|★Crime♥|LMAO -|c|★CHEF BOY4RDEEZNUTS|chat broken -|c| PI EddyChomp|OMG -|c| lordkaelros|IT HAPPENED -|c| QuagGod|FIRST BLOOD HYPE -|c| lordkaelros|GG -|c| LifeisDANK|AYYYY -|c| StAlRuth|AYYYYYYY -|choice|switch 2| -| -|switch|p1a: Fatty|Chansey, F|542/642 -|turn|945 -|c| JacobWorld|turn 944 -|c|★Crime♥|this chat tho xD -|c| QuagGod|LOOOOOOOOOOL -|c| Kyorem|KILZZ -|c| LifeisDANK|REKT -|c| lordkaelros|KEEPO -|c| lordkaelros|LMAO -|c| LifeisDANK|TEKY -|c|+Frizy|pretty sure he still wins but still -|c|★Crime♥|this chat is op -|c| LifeisDANK|GG -|c| Nortellaz|Alright, bae can wait. I'm staying for more murders. -|c| StAlRuth|G RIP -|c| PI EddyChomp|GLISCOR WAS KO'D -|c| ClassifiedArea|THE KO -|c|★Crime♥|this chat is seriously op -|c| CoolSwag2015|**FIRST BLOOD** -|c| LifeisDANK|GG -|c| goodguygastly|You called? -|c| Rath111|hit 1000 -|c| LifeisDANK|https://www.youtube.com/watch?v=u9ymUX1fJLw -|c| StAlRuth|ONE F = ONE RESPECT -|c| hey i'm pikachu|**NO PEACE** -|c| No 1 Machop Fan|what Crime♥ said :p -|c| Rath111|c'moooooooooon -|c| StAlRuth|FFFFFFFFF -|c| Rath111|hit that 1000 -|c| No 1 Machop Fan|oh no -|c| BaconChest|1 down, 11 to go....im on team draw -|c| No 1 Machop Fan|Chansey vs. Chansey -|c| hey i'm pikachu|*CRIME HAS COMMITTED A CRIME** -|c| Kyorem|300 years later... FIRST BLOOD -|c|★Crime♥|guys -|c|★Crime♥|will i win? -|c|★Crime♥|:o -|c| LifeisDANK|AYY -|c| Gaussfield|possibly -|c|★Crime♥|i soo want to win :( -|c| QuagGod|tfw first blood: -|c| LifeisDANK|YOU GO TTHIS Bau -|c| CoolSwag2015|dont think so tbh -|c| LifeisDANK|BAe -|c| Nortellaz|The game's gonna end in a draw. -|c|★Crime♥|<3 -|c| QuagGod|"NIGGA WE MADE IT" -|c| PI EddyChomp|Lol -|choice|switch 4|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|946 -|c|★Crime♥|AYYY -|c| BaconChest|nah nah got too excited crime -|c|★Crime♥|im gonna switch -|c|★Crime♥|and lose'' -|c| Gaussfield|same place -|c| hey i'm pikachu|**4 more turns** -|c| Fryerstarter|WOAH -|c| Gaussfield|let's go -|c|★Crime♥|joke -|c| Fryerstarter|FINALLY LOADED -|choice|switch 4|move 1 -| -|switch|p1a: Fatty|Chansey, F|542/642 -|move|p2a: Chansey|Seismic Toss|p1a: Fatty -|-damage|p1a: Fatty|442/642 -| -|turn|947 -|c| QuagGod|950s **HYPE** -|c| lordkaelros|played -|c| Gaussfield|THE PLAYS THOUGH -|c| PI EddyChomp|And he goes for an OHKO!! -|choice|switch 4|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|948 -|c| lordkaelros|13 tosses -|c| Gaussfield|oh -|choice|switch 4|switch 5 -| -|switch|p1a: Fatty|Chansey, F|442/642 -|switch|p2a: Heatran|Heatran, F, shiny|332/386 par -|-damage|p2a: Heatran|284/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|308/386 par|[from] item: Leftovers -|turn|949 -|c|★Crime♥|no ty -|c| PI EddyChomp|Dis Chansey tho:D -|c|★Crime♥|time for a other strategy -|c|★Crime♥|uhmmmmm -|c|★Crime♥|guys -|c| CriclesAreRound|what turn is this ? -|c|★Crime♥|lets make cobalion back to life -|c|★Crime♥|<3 -|c|+Frizy|oh hey good thing you sacced that gliscor -|c|★Crime♥|somehow -|c| hey i'm pikachu|949 -|c| hey i'm pikachu|**1 more** -|c| PI EddyChomp|950 -|c| Kuronachan|i cant believe i missed first blood -|c| Gaussfield|9 5 0 h y p e -|c| Kuronachan|im a disgrace -|c| QuagGod|rip -|c| PI EddyChomp|LOL -|c| lordkaelros|yes, you are -|c| LifeisDANK|AYyy -|choice|switch 5|switch 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|284/363 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|306/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|950 -|c| CoolSwag2015|**TURN 950!1!!!1!!** -|c| StAlRuth|banned from PS -|c|★Crime♥|oke -|c|★Crime♥|its time to burn this tenta! -|c| StAlRuth|for missing FIRST BLOOD -|c| Kuronachan|950 HYPE -|c| PI EddyChomp|**HE MAKES THE GOAL!!!** -|c| hey i'm pikachu|__95000000000000__ -|c| Kuronachan|74 more -|c| Kuronachan|74 more... -|choice|switch 5|switch 4 -| -|switch|p1a: Fatty|Chansey, F|442/642 -|switch|p2a: Heatran|Heatran, F, shiny|308/386 par -|-damage|p2a: Heatran|260/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|284/386 par|[from] item: Leftovers -|turn|951 -|c| QuagGod|950 TURNS :O -|c| Gaussfield|oh -|c| CoolSwag2015|951* -|c| Dual Screens Mamo|tfw i cant load -|c| Enzonana|no defog? -|c|★Crime♥|i have defog -|c| QuagGod|rip dual screens mamo -|c| Aluminion|74 turns left (this is 10 bit binary) -|c| Aluminion|and 2^10 = 1024 -|c| Rath111|oh fuck -|choice|switch 5|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|306/363 -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: I <3 Stall|Sableye-Mega, M|264/301 -| -|-heal|p2a: Heatran|308/386 par|[from] item: Leftovers -|turn|952 -|c| lordkaelros|Or so you claim -|c| lordkaelros|We need to test the legend -|c| Rath111|they store the turns in 10 bits? -|c| Rath111|but a byte is 8 bits -|c| LifeisDANK|AYYYY whats good -|c|★CHEF BOY4RDEEZNUTS|use plume -|c| drowzee518|2^10=1024 -|choice|switch 4|switch 6 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|306/363 -|switch|p2a: Skarmory|Skarmory, F|141/334 -|-damage|p2a: Skarmory|100/334|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|328/363|[from] item: Black Sludge -|turn|953 -|c|★CHEF BOY4RDEEZNUTS|do it -|c| drowzee518|lets hit 1025 -|c| Aluminion|i don't know what im talking about -|c| Aluminion|i'm joking -|c| Gaussfield|here we go -|c|★CHEF BOY4RDEEZNUTS|that defog doe -|c|★Crime♥|defog or whirlwind -|c|★Crime♥|? -|c|+Frizy|yes waste the fogger -|c| Aluminion|i never studied a single minute of computer science -|c| Rath111|it's atleast 2 bytes -|c| StAlRuth|https://soundcloud.com/boxofkangaroos/littleroot-jam -|c| TheCanadianWifier|1 defog left -|c| TheCanadianWifier|LOL -|c| Nortellaz|Brave Bird -|c| drowzee518|im a comp sci major -|c| CoolSwag2015|1 defog left o.o -|c| QuagGod|StAlRuth that's fire -|c| Rath111|since 1 byte is a max of 255 if it's unsigned -|c| CriclesAreRound|what is going on the battle isnt loading... -|c| QuagGod|:o -|c| drowzee518|i shud prolly know this -|c| drowzee518|but w/e -|c| Aluminion|yeah true -|choice|switch 6|move 1 -| -|switch|p1a: TheMoreYouKnow|Jirachi|205/403 -|move|p2a: Skarmory|Brave Bird|p1a: TheMoreYouKnow -|-resisted|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|145/403 -|-damage|p2a: Skarmory|80/334|[from] recoil|[of] p1a: TheMoreYouKnow -| -|-heal|p1a: TheMoreYouKnow|170/403|[from] item: Leftovers -|turn|954 -|c| drowzee518|its 6am -|c| drowzee518|i dont know anything rn -|c| lordkaelros|skarm sweep incoming bois -|c| LifeisDANK|6am too bro -|c| LifeisDANK|east coaster? -|c| drowzee518|y -|c| hey i'm pikachu|intense -|c| lordkaelros|430 pm O.o -|c| BaconChest|oooh the mind games here are too real -|c| ZzamanN|woah fuck -|c| Rath111|65535 is the max unsigned number for 2 bytes -|c| Gaussfield|it's 1am here -|c| ZzamanN|something got KOed -|choice|move 4|switch 5 -| -|switch|p2a: Chansey|Chansey, F|360/642 -|-damage|p2a: Chansey|280/642|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Chansey -|-fail|p2a: Chansey -| -|-heal|p1a: TheMoreYouKnow|195/403|[from] item: Leftovers -|turn|955 -|c| quay4|omg -|c| i am having fun|TheCanadianWifier you gonna narrate this replay? -|c| LifeisDANK|git good sleep is for never -|c| BaconChest|eyyyyy -|c| i am having fun|every turn -|choice|switch 4|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Toxic|p1a: I <3 Stall -|move|p1a: I <3 Stall|Toxic|p2a: Chansey|[from]Magic Bounce -|-status|p2a: Chansey|tox -| -|-damage|p2a: Chansey|240/642 tox|[from] psn -|turn|956 -|c| TheCanadianWifier|nah LOL -|c| Enzonana|plays plays -|c| BaconChest|get played -|c| CriclesAreRound|1000 is incoming -|c| lordkaelros|rekt -|c| TheCanadianWifier|OOHHHHHH -|c| Cryolite|its almost certainly using the base int number type in whatever language PS is written in -|c|★Crime♥|all planned -|c| Cryolite|which is 32/64 bits -|c| StAlRuth|let's fill the `u16` LADIES AND GENTOOMEN -|c| Cryolite|ie several billion -|c| Rath111|if it's an int omg 4billion turns -|c| Kuronachan|its over -|c| Rath111|ahahahaa -|choice|switch 5|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: Fatty|Chansey, F|442/642 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|957 -|c| Kuronachan|chansey is over -|c| No 1 Machop Fan|good thing it doesn't have Minimise -|c| Dual Screens Mamo|I have no idea what happening. but i do know that its seeking -|c| CriclesAreRound|2000 years latter..... -|c| Eon_Theory|oh my god this is still happening -|choice|switch 3|move 3 -| -|switch|p1a: Redbull|Clefable, M|297/393 tox -|move|p2a: Slowbro|Toxic|p1a: Redbull -|-fail|p1a: Redbull|tox -| -|-heal|p1a: Redbull|321/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|297/393 tox|[from] psn -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|958 -|c| ZzamanN|**3 M O R E T U R N S B O I S** -|c| PI EddyChomp|9999999999 Turns Later............... -|c| QuagGod|will chef and crime hit the 1000 milestone? -|c| CriclesAreRound|that redbullllllllllllll -|c| QuagGod|will another fat mon die? -|choice|switch 5|switch 6 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|switch|p2a: Heatran|Heatran, F, shiny|308/386 par -|-damage|p2a: Heatran|260/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|284/386 par|[from] item: Leftovers -|turn|959 -|c| Nortellaz|That Clefable is stacked with pp -|c| Nortellaz|Too bad it's poisoned -|c| QuagGod|will chef pull in with that clef sweep? -|c| Kuronachan|by the time this ends we'll get half life 3 -|c|★CHEF BOY4RDEEZNUTS|redbull sounds AMAZING right now -|c| QuagGod|find out next time on -|c| CriclesAreRound|this battle has more ppl than most showdown room lol -|c| QuagGod|dragon ball z -|c| LifeisDANK|rebull is gross -|c| LifeisDANK|I like Nos -|c| quay4|yep -|c| lordkaelros|I don't know what nos is -|c| LifeisDANK|energy drink -|c| lordkaelros|redbull is gross though -|c| Dual Screens Mamo|yo real talk fruit punch Nos is awesome -|c| QuagGod|i dont like energy drinks -|c| Rath111|redbull gives cancer -|c| LifeisDANK|that doesnt taste like gasoline -|c| QuagGod|esp not red bull that's nasty af -|choice|switch 6|switch 6 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|328/363 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|350/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|960 -|c| CriclesAreRound|bluebull is redbull's brother BOOM! -|c| QuagGod|e_e -|c| ZzamanN|Oh I missread -|c| LifeisDANK|dual screens knows what up -|c|★CHEF BOY4RDEEZNUTS|cancer gives you cancer -|c| lordkaelros|This battle also gives cancer -|c| ZzamanN|I thought it was 999 -|c| lordkaelros|we're stil watching -|c| ZzamanN|its only 959 -|c|★Crime♥|960 -|c| ZzamanN|rip -|c| Rath111|gives you cancer gives you cancer -|c| Help you ladder|^ -|c| BaconChest|why did i click swtichch sides....nuuuuuu -|c|★CHEF BOY4RDEEZNUTS|trump gives america cancer -|c| QuagGod|ZzamanN dw it'll be there in no time -|c| TheCanadianWifier|lol BaconChest -|c| QuagGod|lol chef -|c| Rath111|touche -|c| Nortellaz|Convo time: Favorite music artists people?!?! -|c| LifeisDANK|lets go faster -|c| Help you ladder|metal -|choice|move 4|move 2 -| -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-singleturn|p2a: Slowbro|Protect -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-activate|p2a: Slowbro|Protect -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|961 -|c| LifeisDANK|i wanna see the 1042 mark -|c| QuagGod|i bet -|c| memethany fantango|it actually loaded lmao -|c| CriclesAreRound|cant wait to share the replay after zarel uploads it -|c| QuagGod|the latinos love trump -|c| QuagGod|kappa -|choice|move 4|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|284/386 par -|-damage|p2a: Heatran|236/386 par|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Heatran -|-resisted|p2a: Heatran -|-damage|p2a: Heatran|232/386 par -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|turn|962 -|c|★Crime♥|1% wow -|c|★Crime♥|how -|c| Dual Screens Mamo|OMG WE IN THER NOW?!?! -|c| Dual Screens Mamo|IT LOADED -|c| No 1 Machop Fan|Yay! Something! :p -|c| waifu rosalina|im not loading :[ -|c| LifeisDANK|what loadin -|c| lordkaelros|King Crimson/ Iron Maiden/ Tool/ Snarky Puppy/ Animals as Leaders -|c| No 1 Machop Fan|give it time :p -|choice|move 4|switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|337/394 tox -| -|-damage|p2a: Slowbro|313/394 tox|[from] psn -|turn|963 -|c|★Crime♥|omg -|c| Nortellaz|I love King Crimson <3 -|c|★Crime♥|i have to pee -|c|★Crime♥|so badly -|c| Help you ladder|Crime♥ has 10 seconds left. Crime♥ lost. -|c| No 1 Machop Fan|we're at 963 turns at time of writing -|c|★Crime♥|and i wanna smoke -|c| hey i'm pikachu|just -|c| Aluminion|reveals 5th move: psychic -|c| hey i'm pikachu|do -|c| hey i'm pikachu|it -|c| waifu rosalina|this is more important crime -|choice|switch 3|move 3 -| -|switch|p1a: Fatty|Chansey, F|442/642 -|move|p2a: Slowbro|Toxic|p1a: Fatty -|-status|p1a: Fatty|tox -| -|-damage|p1a: Fatty|402/642 tox|[from] psn -|-damage|p2a: Slowbro|265/394 tox|[from] psn -|turn|964 -|c| waifu rosalina|:[ -|c| Nortellaz|Starless is one of the best songs of all time. -|c| LifeisDANK|JUST DO IT -|c| lordkaelros|Yep -|c|★CHEF BOY4RDEEZNUTS|break the habit smokings bad -|c| CriclesAreRound|the mega stone for eevee is eviolite BOOM! -|c| Kuronachan|for gods sake -|c| Kuronachan|turn off timer -|c| Help you ladder|smoking kills. -|c| lordkaelros|My favourite album is Lizard -|c| Kuronachan|let yourselves be human -|c|★Crime♥|SPARTAAAA :3 -|c| PI EddyChomp|Eeveeite -|c| Kuronachan|for just two minutes -|choice|switch 3|move 1 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Slowbro|Scald|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-crit|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|319/363 -| -|-heal|p1a: U Jelly Bruh?|341/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|193/394 tox|[from] psn -|turn|965 -|c| lordkaelros|Cirkus gives me gossebumps every time -|c| QuagGod|so do you guys think i should go roll up another joint + make more hot cocoa since this wont be over by the time i'm back -|c|★Crime♥|burn please -|c| No 1 Machop Fan|wow, this Chansey is 3 PP away from Struggling! -|c| Cryolite|where was the burn -|c| Gaussfield|THE CRIT THO -|c| QuagGod|or should i just stay here -|c| Help you ladder|Crime♥ has 30 seconds left. -|c| StAlRuth|found this battle's theme -|c| Nortellaz|Starless gives me goosebumps everytime ;P -|c| StAlRuth|http://stalruthvgc.tumblr.com/post/135246181243/theme-of-this -|c| PI EddyChomp|Really -|c| Nortellaz|The song. Not the album. -|choice|switch 3|switch 6 -| -|switch|p1a: Fatty|Chansey, F|402/642 -|switch|p2a: Heatran|Heatran, F, shiny|256/386 par -|-damage|p2a: Heatran|208/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|232/386 par|[from] item: Leftovers -|turn|966 -|c| lordkaelros|I got it -|c| Kuronachan|quag we'll get the smash DLC tonight before this is over -|choice|switch 5|switch 6 -| -|switch|p1a: Redbull|Clefable, M|297/393 tox -|switch|p2a: Slowbro|Slowbro, F|324/394 tox -|-damage|p2a: Slowbro|275/394 tox|[from] Stealth Rock -| -|-heal|p1a: Redbull|321/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|297/393 tox|[from] psn -|-damage|p2a: Slowbro|251/394 tox|[from] psn -|turn|967 -|c|★Crime♥|970 omg -|c| lordkaelros|Starless and Bible black is one of my less liked albums -|c| Chamix|deez nutw <3 -|c| Nortellaz|Yeah, it has like, one good song? -|c| Help you ladder|Crime♥ has 20 seconds left. -|c| QuagGod|aight so more joint + hot cocoa then -|c| Cryolite|bible black happens to be the title of the greatest anime ever made -|c| LifeisDANK|oml -|c| Dual Screens Mamo|^ -|c| Rath111|pr0nz -|c| Kraytoast|is there an actual strategy here? -|c| LifeisDANK|yea -|c| QuagGod|cryolite cory in the house > bible black -|c| LifeisDANK|its called -|c| TheCanadianWifier|yes -|choice|switch 5|move 4 -| -|switch|p1a: Fatty|Chansey, F|402/642 -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 tox -| -|-damage|p2a: Slowbro|346/394 tox|[from] psn -|turn|968 -|c| LifeisDANK|switch -|c| Rath111|stall -|c| lordkaelros|I'd rank them as : Lizard, Red, ITCOTK, Islands, ITWOP -|c| PI EddyChomp|Crime has 100000 seconds ledt. -|c| Gaussfield|HOOOOOOOOOOOOOO -|c| QuagGod|its called not winning cryolite -|c| Dual Screens Mamo|Bible Black has tons of..."plot" -|c|★CHEF BOY4RDEEZNUTS|bait and stealth rocks but regen is a botch -|c| lordkaelros|'plot' -|c| QuagGod|*not losing -|c| CriclesAreRound|the megastone for dragonite is...........dragonite BOOM! -|c| lordkaelros|kek -|c| Help you ladder|botch -|c| No 1 Machop Fan|wow, SLowbro stil has a lot of Slack Off -|c| lordkaelros|I've played the VN -|c| Cryolite|o shit ur right -|c| No 1 Machop Fan|*Slowbro -|c| Nortellaz|What about the later albums? -|c| lordkaelros|'played' -|c| QuagGod|i'd say its a pretty nice strat -|c| Nortellaz|Lol -|c| QuagGod|hue -|c| Cryolite|nothing can stop cory -|choice|move 3|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|232/386 par -|-damage|p2a: Heatran|184/386 par|[from] Stealth Rock -|move|p1a: Fatty|Wish|p1a: Fatty -| -|-heal|p2a: Heatran|208/386 par|[from] item: Leftovers -|turn|969 -|c| lordkaelros|Discipline is awesome -|c|★Crime♥|when should we go for the defog guys? -|c| PI EddyChomp|CriclesAreRound no Dragoniteite -|c| Help you ladder|1 wish 1 toxic -|c| Nortellaz|Debut is my favorite, followed by Red, then Discipline -|c| bleycker|every pp has to be down no? -|c| Kuronachan|969 (lenny) -|c| Gaussfield|do they have rocks? -|c| Nortellaz|And then Lizard -|c| Dual Screens Mamo|Bible Black has Chicks that grow dicks on command. BEST. ANIME. EVER -|c| memethany fantango|turn 1011 -|c| QuagGod|lol kuro -|choice|switch 4|switch 6 -| -|switch|p1a: TheMoreYouKnow|Jirachi|195/403 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|403/403|[from] move: Wish|[wisher] Fatty -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|970 -|c| CriclesAreRound|you know golduck is so OP ubers banned it XD -|c| PI EddyChomp|**One more turn** -|c| Help you ladder|100* -|c| lordkaelros|for whayt -|c| Kuronachan|golduck > primal groudon -|c|+Frizy|did that heatran have a lava plume -|c| LifeisDANK|golduck is baller -|c| PI EddyChomp|**30 more turns** -|c| BaconChest|finally freaking caught up...never switching sides again, Crime<3 all the way -|choice|switch 4|switch 4 -| -|switch|p1a: Fatty|Chansey, F|402/642 -|switch|p2a: Chansey|Chansey, F|240/642 -|-damage|p2a: Chansey|160/642|[from] Stealth Rock -| -|turn|971 -|c|@Former Hope|yes -|c|★CHEF BOY4RDEEZNUTS|he wont use it -|c|+Frizy|why the fuck -|c|+Frizy|did you go to jira then -|c| CriclesAreRound|chansey face of -|c|+Frizy|lol -|c|★CHEF BOY4RDEEZNUTS|hes a pussy -|c| lordkaelros|chansey gonna die -|c| lordkaelros|kek -|c|★Crime♥|shes* -|c| Nortellaz|King Crimson is probably only 10th in my favorite artists though. Sorry lordkaelros ;) -|c|★Crime♥|im not a HE -|c| LifeisDANK|My gurl AYYY -|c| lordkaelros|It's chill -|c| Help you ladder|we don't care about gender, just paly -|c| Help you ladder|play -|c| hey i'm pikachu|*pray -|c|★Crime♥|how rude -|c| CoolSwag2015|Crime -|choice|switch 6|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|972 -|c| Black Spindle|get ur tits out -|c| PI EddyChomp|OH SNAP -|c|★Crime♥|LOL -|c| CoolSwag2015|i dont think that you should say that youre a girl -|c| TheCanadianWifier|... -|c| TheCanadianWifier|LOL -|c| CoolSwag2015|where theres like 50 people -|c| PI EddyChomp|LOL -|c| lordkaelros|You should listen to Snarky Puppy -|c|★CHEF BOY4RDEEZNUTS|(entire chat unzips pants) -|c| Rath111|why should a girl not be allowed to say she's a girl? -|c| lordkaelros|and Animals as Leaders -|c| BaconChest|deeznuts trying that psychological warfare, not realizing that Crime is a superhero who is immune to trolling.... -|c| Nortellaz|Ween's my fave band, overall. Followed very closely by Beatles -|c| lordkaelros|Everyone should listen to them -|c| Help you ladder|unzip? but i have shorts -|c| lordkaelros|They are gods -|c|★CHEF BOY4RDEEZNUTS|SNARKY PUPPY IS THE SHIT OMG YOURE AMAZING -|c| Dual Screens Mamo|I can fap to this -|choice|switch 6|move 1 -| -|switch|p1a: Fatty|Chansey, F|402/642 -|move|p2a: Chansey|Seismic Toss|p1a: Fatty -|-damage|p1a: Fatty|302/642 -| -|turn|973 -|c| StAlRuth|everyone be brave birds -|c| CoolSwag2015|rath111 im just recommending her not to -|c| QuagGod|theres no girls on the internet rath111 -|c| Rath111|so? -|c| Nortellaz|First time I've heard of them... -|c| lordkaelros|Snarky Puppy is bae -|c| LifeisDANK|Tits are awesome, my favorite are the tufted tit mouse. so cute -|c| Nortellaz|Ween, anyone? :( -|c| lordkaelros|Hell-oween? -|c| Nortellaz|I'll put snark puppy on my youtube right now -|choice|move 3|switch 3 -| -|switch|p2a: Florges|Florges, F|102/360 -|-damage|p2a: Florges|57/360|[from] Stealth Rock -|move|p1a: Fatty|Wish|p1a: Fatty -| -|turn|974 -|c| TheCanadianWifier|g.i.r.l. = guy in real life -|c| No 1 Machop Fan|here we go... -_- -|c| Help you ladder|Turn 944: best turn in this match yet -|c| lordkaelros|Listen to the whole album: We like it here -|c| StAlRuth|it begins._. -|choice|move 2|move 1 -| -|move|p2a: Florges|Moonblast|p1a: Fatty -|-crit|p1a: Fatty -|-damage|p1a: Fatty|209/642 -|move|p1a: Fatty|Toxic|p2a: Florges -|-status|p2a: Florges|tox -| -|-heal|p1a: Fatty|530/642|[from] move: Wish|[wisher] Fatty -|-damage|p2a: Florges|35/360 tox|[from] psn -|turn|975 -|c| CoolSwag2015|**25 turns to 1000** -|c| LifeisDANK|AH\ -|c| CoolSwag2015|n.n -|c| QuagGod|o shit -|c| TheCanadianWifier|AAYE -|c| lordkaelros|Dead flower is dead -|c| Rath111|let the struggle begin -|c| Help you ladder|rip flower -|c| QuagGod|something's dying -|c|★CHEF BOY4RDEEZNUTS|floreg dies to rox -|c| Nortellaz|Lordkaelros, got a song to recommend? -|c| Dual Screens Mamo|OH -|c| TheCanadianWifier|florges is dead! -|c| LifeisDANK|gg -|c| QuagGod|ayyyy -|c| CriclesAreRound|rip flower -|c| Enzonana|rip chansey -|c| StAlRuth|F -|c| CoolSwag2015|when it gets to 1000 ill screenshot -|c| StAlRuth|F -|c| StAlRuth|F -|c| Nortellaz|By Snarkypuppy I mean -|choice|switch 4|switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|976 -|c| PI EddyChomp|25 turns left -|c|★Crime♥|my goal is turn 1000 -|c| PI EddyChomp|**24 TURNS LEFT** -|c| lordkaelros|We like it here -|c|★Crime♥|next time i will make it 2000 turns -|c| LifeisDANK|hype -|c| CriclesAreRound|defog on skarm? -|c| lordkaelros|*sorry song -|c| StAlRuth|out of pp -|c| lordkaelros|What about me -|c| bleycker|probably all gone -|c| StAlRuth|i think -|c| Kuronachan|50 turns to go -|c| StAlRuth|maybe one left -|c| lordkaelros|or outlier -|c|★CHEF BOY4RDEEZNUTS|cob and chansey are low too -|c| Nortellaz|The whole album? -|choice|switch 4|move 3 -| -|switch|p1a: Fatty|Chansey, F|530/642 -|move|p2a: Slowbro|Toxic|p1a: Fatty -|-status|p1a: Fatty|tox -| -|-damage|p1a: Fatty|490/642 tox|[from] psn -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|977 -|c| Help you ladder|RIP chansey -|c| lordkaelros|The entire album is amazing -|c|+Frizy|theres 1 fog left -|c| lordkaelros|Just start with the first song -|c| CriclesAreRound|slowbros got those slack offs tho -|c| Nortellaz|Dude I'm listening to Shofukan. -|c| Nortellaz|SO MESMERIZIG -|c| bleycker|rip chansey? natural cure man -|c| lordkaelros|Shofukan is also great -|c| lordkaelros|Listen to Sleeper -|c| Rath111|20 seconds -|c| lordkaelros|You will be mindfucked -|c| Help you ladder|Crime♥ forfeited. -|c| Nortellaz|If this is the first song then I'm already sold -|c| Rath111|until crime loses -|choice|switch 3|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|341/363 -|move|p2a: Slowbro|Toxic|p1a: U Jelly Bruh? -|-immune|p1a: U Jelly Bruh?|[msg] -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|201/394 tox|[from] psn -|turn|978 -|c| Rath111|10 seconds -|c| TheCanadianWifier|crime ? ? ? ? ? -|c| Rath111|OMG -|c| Help you ladder|Crime♥ lost. -|c|★CHEF BOY4RDEEZNUTS|help you ladder lol -|c| TheCanadianWifier|10 seconds -|c| CriclesAreRound|phew -|c| TheCanadianWifier|dont time out now -|c| Rath111|GO -|c| Rath111|FAST -|choice|switch 3|move 4 -| -|switch|p1a: Fatty|Chansey, F|490/642 -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 tox -| -|-damage|p2a: Slowbro|298/394 tox|[from] psn -|turn|979 -|c| Gaussfield|god these timers -|c|★Crime♥|kay -|c| BayFence|the person who gets this record will be cheef -|c|★Crime♥|i wanna smoke -|c| CriclesAreRound|u cant -|c| Help you ladder|this match can be summarised as: good shit, badly wiped. -|c| Dual Screens Mamo|NO -|c|★CHEF BOY4RDEEZNUTS|then smoke -|choice|switch 3|switch 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|switch|p2a: Chansey|Chansey, F|160/642 -|-damage|p2a: Chansey|80/642|[from] Stealth Rock -| -|turn|980 -|c| frailoldman|mitch is fat -|c| QuagGod|Crime♥ forfeited -|c| ClassifiedArea|YOU GOT DIS CRIME -|choice|switch 6|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|981 -|c| Nortellaz|lordkaelros, let me give you a recommendation: Try Transdermal Celebration by Ween -|choice|switch 6|move 1 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|move|p2a: Chansey|Seismic Toss|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|263/363 -| -|-heal|p1a: U Jelly Bruh?|285/363|[from] item: Black Sludge -|turn|982 -|c| quay4|the switch game -|c| Cryolite|will rapid spin kill? -|choice|move 4|move 1 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Chansey -|-damage|p2a: Chansey|65/642 -|move|p2a: Chansey|Seismic Toss|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|185/363 -| -|-heal|p1a: U Jelly Bruh?|207/363|[from] item: Black Sludge -|turn|983 -|c| Help you ladder|no -|c| lordkaelros|lmao -|c| QuagGod|rof -|c|★CHEF BOY4RDEEZNUTS|he dies to rocks -|c| TheCanadianWifier|go to sab now -|c| No 1 Machop Fan|this'll be interesting -|c|★Crime♥|rapid skin op -|choice|switch 6|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|984 -|c| Dual Screens Mamo|THE BATTLE OF TITANS -|c| ZzamanN|At least it wasnt 1% -|c| Help you ladder|dual mammography mamo -|c| TheCanadianWifier|Crime play this one out pls -|choice|switch 4|move 1 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Chansey|Seismic Toss|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|303/403 -| -|-heal|p1a: TheMoreYouKnow|328/403|[from] item: Leftovers -|turn|985 -|c| Kuronachan|COME ON CHANSEY -|c| StAlRuth|PLS -|c| Kuronachan|PULL THROUGH -|c| lordkaelros|What kind of band is ween? -|c| CriclesAreRound|imagine if magic gaurd prevented struggle recoil damage.... -|c| CoolSwag2015|chansey gonna go down -|c| TheCanadianWifier|it would be a travesty to see such a great game end with a forfeit at 6v5 -|c| QuagGod|CHANSEY GOT THIS -|c| lordkaelros|First time I've heard of them -|c| QuagGod|GO FOR THE W -|c| Nortellaz|Ween? -|c| Help you ladder|finish it on 1000 -|c| LifeisDANK|ayy -|c| CriclesAreRound|C H A N S E Y -|c| Ed✔️|gj CHEF -|c| Rath111|NO -|c| StAlRuth|LET'S HAVE THIS GO ON ALL NIGHT -|c| Rath111|GO PAST 1000 -|c| Rath111|KEEP GOING -|c| Kuronachan|#TEAMCHANSEY -|c| Help you ladder|no -|c| Help you ladder|1000 -|c| StAlRuth|IT'S ONLY 10:00PM -|c| Rath111|you must go forever -|c|★CHEF BOY4RDEEZNUTS|crime halve yo team is almost dead -|c| lordkaelros|second blood incoming -|c| BayFence|go cheef this record is 4 u -|c| QuagGod|# T E A M C H A N S E Y -|c| Gaussfield|which one is team chansey? -|c| Nortellaz|Loving Shofukan btw <3 -|c| StAlRuth|both of them :^) -|c| lordkaelros|See? -|c|★Crime♥|CHEF you were supposed to go bed 8 hours ago -|c| Rath111|crime, TURN SUPER SAIYAN -|c| QuagGod|crime Gaussfield -|c| Kuronachan|#11% -|c| lordkaelros|Snarky Puppy is insane -|choice|move 2|move 1 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Chansey -|-status|p2a: Chansey|par -|move|p2a: Chansey|Seismic Toss|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|228/403 -| -|-heal|p1a: TheMoreYouKnow|253/403|[from] item: Leftovers -|turn|986 -|c| CriclesAreRound|C H A N S E Y -|c| Kuronachan|OH SHIT LOOK AT THIS BITCH -|choice|switch 4|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|987 -|c| CoolSwag2015|florges dies next switchin and chansey is almost down -|c| Kuronachan|11% AND SHAVING OFF THAT HELATH -|c| Help you ladder|;D -|c| Nortellaz|Doesn't his Skarm have Defog? -|c| Cryolite|chansey and florg both die to rock on the switch -|choice|switch 6|move 1 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|207/363 -|cant|p2a: Chansey|par -| -|-heal|p1a: U Jelly Bruh?|229/363|[from] item: Black Sludge -|turn|988 -|c| Cryolite|skarm cant roost -|c| QuagGod|hah -|c| QuagGod|gottem -|c| Chamix|OOOOOOOOOOOOOOOOOOOOO -|c| PI EddyChomp|idk -|c| Kuronachan|NO CHANSEY YOU CAN DO THIS -|c|★CHEF BOY4RDEEZNUTS|HERE WE GOOOOOO -|c| Dual Screens Mamo|E Z -|c|★Crime♥|oke im smoking this game is gettin on my nerves -|c| Rath111|OMG -|c| Help you ladder|this game is older than my dad -|c|★Crime♥|im literally crying -|c|★Crime♥|lol -|c| QuagGod|crime -|c| PI EddyChomp|CHANSEY NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO -|c| LifeisDANK|dony cry bby -|c| Kuronachan|dont worry crime -|c|+Frizy|bro i already told you that you lost -|c| No 1 Machop Fan|smoking is for losers -|c| Cryolite|na dood ur gonna play this -|c| QuagGod|is it a blunt/joint -|c|+Frizy|could've saved urself an hour -|c| Kuronachan|it ends at 1024 -|c| QuagGod|or tobacco -|c| No 1 Machop Fan|quit smoking or forfeit the match -|c|★Crime♥|lifeis, kuro thank you guys <3 -|c| Rath111|why would it end at 1024? -|c| CroppedPorn|wew -|c| LifeisDANK|AYyy -|c| Help you ladder|because 2^10 -|c| TheCanadianWifier|quit smoking today before you die tomorrow :( -|c| Kuronachan|<3 -|c| CriclesAreRound|dont forfeit -|c| bleycker|i just wanna see the 1000 -|c| Rath111|a byte is 8 bits -|c| Nortellaz|The only good that came from this match is I have an awesome new band to get myself into now. -|choice|move 4|move 1 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Chansey -|-damage|p2a: Chansey|52/642 par -|move|p2a: Chansey|Seismic Toss|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|129/363 -| -|-heal|p1a: U Jelly Bruh?|151/363|[from] item: Black Sludge -|turn|989 -|c| PI EddyChomp|14 Turns LEFT -|c| CriclesAreRound|1024 -|c| Kuronachan|THAT DAMAGE -|c| Cryolite|its not gonna end at 1024 -|c|@Former Hope|It won't end at 1024. -|c|★CHEF BOY4RDEEZNUTS|YESTERDAY YOU SAID TOMORROW -|c| Gaussfield|just do what you want crime -|c| Kyorem|CHANSEY NO -|c| QuagGod|that 14 TURN HYPE -|c|★CHEF BOY4RDEEZNUTS|JUST DO IT -|choice|switch 6|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|264/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|990 -|c| Cryolite|that limit was put in PO, but its not here -|c| Cryolite|we have endless battle which does the same thing -|c| Help you ladder|**cries manly tears** -|c|★Crime♥|im crying. -|c| hey i'm pikachu|**10 MORE TURNS** -|c| ZzamanN|**DONT LET YOUR DREAMS BE DREAMS** -|c| QuagGod|crime dw -|c| Kuronachan|chansey is putting in so much fucking work -|c| QuagGod|i'll comfort u -|c| LifeisDANK|HYPE -|c| Kuronachan|#TEAMCHANSEY -|c| Rath111|10 more turns -|c| waifu rosalina|how long has this battle been going on... -|c| QuagGod|w/ this dance -|c| Black Spindle|today history is made -|c| CriclesAreRound|34 more turns -|c| quay4|**yester day you say tommorrow** -|c| hey i'm pikachu|7 hour -|c| hey i'm pikachu|s -|c| QuagGod|(~'o')~ -|c|★Crime♥|/me falls sadly down on the ground -|c| Help you ladder|**Chansey used Rest** -|c| PI EddyChomp|**TURN 1000 HYPE COME ON!!!!!!!!!!!!!!!!** -|c| QuagGod|~('o'~) -|c| Black Spindle|but a women cannot be in good history so we need to edit crime out -|c| TheCanadianWifier|9 hours ish? -|c| CoolSwag2015|crime :( -|c| LifeisDANK|CRIME BBY NO -|c| waifu rosalina|7 fucking hours HELLO -|choice|move 4|move 1 -| -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -|cant|p2a: Chansey|par -| -|turn|991 -|c| waifu rosalina|8?!?!?! -|c| lordkaelros|10 ore turns boys -|c| Kuronachan|she isn't going down without a fight -|c|★CHEF BOY4RDEEZNUTS|damn -|c| PI EddyChomp|9 -|c| Kuronachan|I love her -|c| waifu rosalina|oml -|c| QuagGod|GO CRIME -|c| LifeisDANK|-3- -|choice|switch 6|move 1 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|151/363 -|move|p2a: Chansey|Seismic Toss|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|51/363 -| -|-heal|p1a: U Jelly Bruh?|73/363|[from] item: Black Sludge -|turn|992 -|c| bleycker|t wave is pretty bad rn isnt it? -|c| Rath111|OH SHIT -|c| QuagGod|# T E A M C R I M E -|c| Help you ladder|RIP tenta -|c| Kuronachan|OH MY GOD -|c| quay4|**8** -|c| Gaussfield|t wave is saving lives -|c| QuagGod|O SHI -|c| QuagGod|HYPE -|c| Kuronachan|IS SHE GOING TO DECIMATE EVERYTHING BUT SABLE -|choice|switch 6|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Chansey|Toxic|p1a: I <3 Stall -|move|p1a: I <3 Stall|Toxic|p2a: Chansey|[from]Magic Bounce -|-fail|p2a: Chansey -| -|turn|993 -|c|★Crime♥|:) -|c| Help you ladder|LOL -|c| waifu rosalina|i need to see these teams tho -|c| waifu rosalina|also -|c| CoolSwag2015|lol -|c| LifeisDANK|ayyy -|c| Help you ladder|toxipoison -|c|★Crime♥|AYYYYYYYYYYY -|c| PI EddyChomp|U Jelly Bruh? -|c| QuagGod|CRIME ITS WORTH THE TIME -|choice|switch 4|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|253/403 -|move|p2a: Chansey|Toxic|p1a: TheMoreYouKnow -|-immune|p1a: TheMoreYouKnow|[msg] -| -|-heal|p1a: TheMoreYouKnow|278/403|[from] item: Leftovers -|turn|994 -|c| ZzamanN|Get fucking played -|c| Gaussfield|oh -|c| QuagGod|DO THE CRIME, ITS WORTH THE TIME -|c| Gaussfield|mmmmmmmwelp -|c| QuagGod|everyone -|c| PI EddyChomp|6 TURNS LEFT -|c| QuagGod|hype her up -|c| Help you ladder|FFFFFFFFFFF I pressed F5 -|c| LifeisDANK|HYPE -|c| QuagGod|6 turns -|c| No 1 Machop Fan|hi ZzamanN -|c|★Crime♥|i love you all <3 -|c| LifeisDANK|HYPE BBY -|c| quay4|**waiting for turn 1000** -|c| Dual Screens Mamo|<3333 -|c| QuagGod|#HYPEITUP -|c| LifeisDANK|AYYY -|c|★Crime♥|im just very happy you guys are watching me -|c| Kuronachan|to not -|c| Kuronachan|twould be a crime -|c|★Crime♥|makes me feel popular -|c| Help you ladder|longest video on youtube -|c| bleycker|someone forfeit turn 999 -|c| CriclesAreRound|Crime you get all the weed in the world if this stretches to 1024 turns -|c| lordkaelros|HYPE -|c| lordkaelros|HYPE -|c| Gaussfield|**6 t u r n s** -|c| bleycker|that would be epic -|c| lordkaelros|HYPE -|choice|switch 4|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Chansey|Toxic|p1a: I <3 Stall -|move|p1a: I <3 Stall|Toxic|p2a: Chansey|[from]Magic Bounce -|-fail|p2a: Chansey -| -|turn|995 -|c| Nortellaz|Crime, get too turn 999. Then quit the game. -|c| Rath111|NO -|c|★Crime♥|oke -|c| Help you ladder|//chansey i fap so hard to you// -|c| LifeisDANK|NO -|c| Kuronachan|crime after this im going to best friend you -|c| The Mighty Ho|^ -|choice|switch 3|move 2 -| -|switch|p1a: Fatty|Chansey, F|490/642 -|cant|p2a: Chansey|par -| -|turn|996 -|c| Rath111|NOOOOOOO -|c| CriclesAreRound|dont do that -|c| LifeisDANK|HYPE -|c| TheCanadianWifier|I swear to god if I see a forfeit at turn 1000 I''m going to have a stern talk with your parents >:( -|c| Nortellaz|Leave us all high and dry in revenge of your loss -|c| QuagGod|you get my top 10 weed strands if u pull through this match -|c| CoolSwag2015|NO -|c| frailoldman|give up crime like the little girl you are -|c| Cryolite|chef why did you twave that chansey -|c| No 1 Machop Fan|please keep going and quit smoking instead -|c| ZzamanN|**FOUR TURNS LEFT** -|c| QuagGod|at 1000 turns -|c|★Crime♥|i want infinity pars -|c| Kuronachan|come on crime -|c| CriclesAreRound|1024 and u can smoke all u like -|c|★Crime♥|and ill win -|c|★Crime♥|:D -|c| waifu rosalina|tcw are u rec this -|c| Kuronachan|reach 1024 -|c| LifeisDANK|Ayy -|c|★CHEF BOY4RDEEZNUTS|tried to save tenta -|c| TheCanadianWifier|n -|c| QuagGod|CRIME YOU GOT THIS -|c| QuagGod|GETTEM -|c| Kuronachan|discover if the legend holds truth -|c| Help you ladder|CALL 999 -|c|★Crime♥|yes i got this <3 -|c|★CHEF BOY4RDEEZNUTS|wanted the rapid spin kill -|c| waifu rosalina|i cri -|c| BayFence|chef i think u will get this record bro just win -|c| CriclesAreRound|thats the spirit win this one -|c| QuagGod|#DOTHECRIMEITSWORTHTHETIME -|c|★Crime♥|omg guys please help me -|c| hey i'm pikachu|KILL NURSE JOY -|c|★Crime♥|i have to pee -|c| CoolSwag2015|OH SHIT -|c|★Crime♥|i cant go to the toilet -|c| CroppedPorn|nigga why dont he just switch out -|c| LifeisDANK|LETS GO CRIME AAYYYY -|c|★Crime♥|timer goes so fast -|c| CoolSwag2015|did anyone else notice -|c| Cryolite|piss in a cup -|c| QuagGod|O SHIT -|c| Kuronachan|I'll gladly do the crime hehehe -|c| Rath111|TAKE OFF THE FUCKING TIMER -|c| Nortellaz|Want me to log into your account? ;) -|c| Black Spindle|just plug your fanny -|c| waifu rosalina|just piss ur pants this is too important -|c| Help you ladder|**chansey i want to cum on your egg ♥** -|c| Gaussfield|ohmygod -|c| CoolSwag2015|**1 seismic toss PP left :/** -|choice|switch 3|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Chansey|Toxic|p1a: I <3 Stall -|move|p1a: I <3 Stall|Toxic|p2a: Chansey|[from]Magic Bounce -|-fail|p2a: Chansey -| -|turn|997 -|c| No 1 Machop Fan|XD -|c| QuagGod|CHEF -|c| CriclesAreRound|this battle has a more active chat than <> -|c| QuagGod|turn off -|c| QuagGod|the fkin -|c| ZzamanN|**THREE TURNS LEFT** -|c| QuagGod|timer -|c| QuagGod|pl -|c| hey i'm pikachu|xD -|c| QuagGod|pls -|c| hey i'm pikachu|xD -|c| hey i'm pikachu|xD -|choice|switch 3|move 2 -| -|switch|p1a: Fatty|Chansey, F|490/642 -|move|p2a: Chansey|Toxic|p1a: Fatty -|-status|p1a: Fatty|tox -| -|-damage|p1a: Fatty|450/642 tox|[from] psn -|turn|998 -|c| No 1 Machop Fan|I was gonna say to turn off the timer -|c| hey i'm pikachu|xD -|c| hey i'm pikachu|xD -|c| hey i'm pikachu|xD -|c| ZzamanN|**TWO TURNS LEFT** -|c| Kuronachan|27 turns to go -|c| lordkaelros|3 more turns boys -|c| Help you ladder|RIP chanseys -|choice|switch 3|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|cant|p2a: Chansey|par -| -|turn|999 -|c| QuagGod|2 MOR -Help you ladder was muted by Former Hope for 7 minutes. -|unlink|helpyouladder -|c| LifeisDANK|HYPE -|c| lordkaelros|2 more -|c| Dual Screens Mamo|OMG -|c| lordkaelros|HYPe -|c| ZzamanN|**ONE TURN LEFT** -|c| QuagGod|1 MORE -|c| StAlRuth|IT'S HAPPENING -|c| Dual Screens Mamo|THE PARA -|c| LifeisDANK|HYPE -|c| LifeisDANK|AYYYY -|c| Dual Screens Mamo|HYPE -|c| Gaussfield|**ONE MORE TURN HYPE** -|c| quay4|omg -|c| Nortellaz|FORFEIT -|c| waifu rosalina|rip comp out of wall then go to toilet y/n -|c| Rath111|NO -|c| LifeisDANK|WELCOME 1000! -|c| quay4|nooooo -|choice|switch 4|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|278/403 -|move|p2a: Chansey|Toxic|p1a: TheMoreYouKnow -|-immune|p1a: TheMoreYouKnow|[msg] -| -|-heal|p1a: TheMoreYouKnow|303/403|[from] item: Leftovers -|turn|1000 -|c| Gaussfield|**THIS IS IT BOYS** -|c| Ed✔️|__**1000**__ -|c| Nortellaz|FORFEIT -|c| CoolSwag2015|**TURN 1000 WOO** -|c| The Mighty Ho|CLICK THE X -|c| charizard8888|**1000 TURNS CONGRATULATIONS EVERYONE FOR BEING A PART OF HISTORY 2015** -|c| ZzamanN|**1000 HYPE!!!!!!!!!** -|c| LifeisDANK|AYYY -|c| StAlRuth|http://www.myinstants.com/instant/mlg-airhorn/ -|c| Kuronachan|ITS HERE -|c| CriclesAreRound|1000 -|c| Dual Screens Mamo|WE MADE IT -|c| StAlRuth|http://www.myinstants.com/instant/mlg-airhorn/ -|c| Cryolite|gottem -|c|★Crime♥|omg 1000!!!!!!!! -|c| Rath111|1000000000000000000 -|c| lordkaelros|1000 -|c| QuagGod|HYPE -|c| quay4|hype -|c| lordkaelros|!!!!!!!!!!1 -|c| Kuronachan|OH MY GOFD -|c|@Former Hope|lol -|c| CriclesAreRound|1000 -|c| QuagGod|wait -|c| CriclesAreRound|1000 -|c| The Suicoon|lol -|c| quay4|al; the way -|c| lordkaelros|dingdingdingdingding -|c| CriclesAreRound|1000 -|c|★Crime♥|JEZUS -|c| Gaussfield|**AYYYYYY** -|c| QuagGod|o -|c| CriclesAreRound|1000 -|c| Rath111|KEEP GOING -|c| bleycker|1000!!!!! -|c|@Aurora|what the fuck -|c|★Crime♥|1000 -|c| lordkaelros|JACKPOT -|c|★CHEF BOY4RDEEZNUTS|holy shit the chat lol -|c| Maitre Miltank|HELLO MOTHER -|c| QuagGod|HYPE -|c| CriclesAreRound|100 -|c| Rath111|DO NOT STOP -|c| LifeisDANK|ITS here -|c| CoolSwag2015|TURN 1000 -|c| Cryolite|1000 turn get -|c| CoolSwag2015|WOOOOOOOOOOO -|c|★Crime♥|WHAT THE FUCK -|c| QuagGod|AAAAAAAY -|c| CriclesAreRound|1000 -|c| TheCanadianWifier|hype ! Kappa PogChamp -|c| CriclesAreRound|100 -|c| Kuronachan|MILESTONE OF RTHE YEAR -|c| Rath111|lmao -|c| CriclesAreRound|1000 -|c| ZzamanN|**HAPPY NEW YEARS** -|c| bleycker|turn up chat XD -|c| ZzamanN|**HAPPY NEW YEARS** -|c| BaconChest|kappa -|c| ZzamanN|**HAPPY NEW YEARS** -|c| CriclesAreRound|1000 -|c| ZzamanN|**HAPPY NEW YEARS** -|c| CoolSwag2015|and wow this chat is cancer rn -|c| CriclesAreRound|1000 -|c| CoolSwag2015|lol -|c| travisty1|keep going until someone wins -|c| CriclesAreRound|1000 -|c| LifeisDANK|AYy -|c| The Suicoon|wait a pokemon died? whe did that happen? -|c| quay4|yes this a amizing record of world -|c| charizard8888|**THE CHAT IS CRAZY** -|c| PI EddyChomp|YES EVRYONE CONGRATS FOR COMING HERE TO CELEBRATE 1000 TURNS FOR 2015!!!!!!! YES!!!! -|c| CroppedPorn|**HAPPY NEW YEARS** -|c| watfor|**MOM 10 MORE MINUTES** -|c| QuagGod|GETTEM -|c| QuagGod|HYPE -|c| watfor|**MOM 10 MORE MINUTES** -|c| watfor|**MOM 10 MORE MINUTES** -|c| QuagGod|WE GOT THIS -|c| LifeisDANK|c: -|c| Zenadark|shed up -|c| QuagGod|bro -|c| Eon_Theory|TURN 1000 -|c| Black Spindle|thats one more thing off the bucket list -|c| Eon_Theory|:DDDD -|c| derivations|**it's not new year** -|c| TheCanadianWifier|^^^ mom 10 more minutes -|c|★Crime♥|omg im so happy -|c| Nortellaz|Dear Lord -|c|★Crime♥|1k turns! -|c| charizard8888|**EVERYONE LEARN TO BOLD** -|c| hey i'm pikachu|GG -|c| watfor|hi richard -|c| CoolSwag2015|looooooool -|c| watfor|n_n -|c| QuagGod|# T E A M C R I M E -|c| Kuronachan|*1000* -|c| Gaussfield|people are showing up like crazy -|c| Gaussfield|goodness -|c| mitchisgaye|mitch is gay -|c| quay4|**okay i will learn** -|c| lordkaelros|I posted on ou :p -|c| CriclesAreRound|C H A N S E Y -|c| LifeisDANK|GUYS ITS 620am here -|c| Rath111|1001 -|c| waifu rosalina|my computer literally just froze for about 30 seconds -|c| Rath111|do eet -|c|★CHEF BOY4RDEEZNUTS|HOLY DICK THIS CHAT -|choice|switch 3|move 2 -| -|switch|p1a: Fatty|Chansey, F|450/642 -|move|p2a: Chansey|Toxic|p1a: Fatty -|-status|p1a: Fatty|tox -| -|-damage|p1a: Fatty|410/642 tox|[from] psn -|turn|1001 -|c| BayFence|crime but the record is not for u :s the record is for the player who wins :s -|c| ClassifiedArea|#1000 -|c| CoolSwag2015|looooool -|c|★Crime♥|no -|c| lordkaelros|don't be mean to him -|c|★Crime♥|thats not true! -|c| No 1 Machop Fan|STRUGGLE! -|c| derivations|the record is 2013 -|c| CoolSwag2015|1001 -|c| BayFence|yes its that true -|c| bleycker|ok enough for me gg wp enjoy the rest XD -|c| Rath111|the record is for both players -|c| QuagGod|bay fence -|c| CriclesAreRound|C H A N S E Y -|c| QuagGod|stfu -|c| derivations|go up to 2015 -|c| The Mighty Ho|STRUGGLE TO DEATH -|c| PI EddyChomp|Cyas all!!!!! -|c| CriclesAreRound|C H A N S E Y -|c| LifeisDANK|HYPE -|c| frailoldman|@mitchisgaye i love the name, it speaks to me -|c| QuagGod|dont be mean to crime -|c|★Crime♥|guys im gonna smoke quick oke? -|c| CriclesAreRound|C H A N S E Y -|c| charizard8888|**THANKS CHEF BOY4RDEEZNUTS and Crime FOR NOT LOSING PATIENCE ** -|c| Rath111|fast -|c| StAlRuth|STRUGGLE HYPE -|c|★Crime♥|im soo tired -|c| Rath111|fast -|c| derivations|NO -|c| Joshisgayasfuck|fuck you josh and sean loves primate dick -|c| CoolSwag2015|i wonder when this will end -|c| charizard8888|**THANKS CHEF BOY4RDEEZNUTS and Crime FOR NOT LOSING PATIENCE** -|choice|switch 4|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Chansey|Toxic|p1a: I <3 Stall -|move|p1a: I <3 Stall|Toxic|p2a: Chansey|[from]Magic Bounce -|-fail|p2a: Chansey -| -|turn|1002 -|c| PI EddyChomp|See all of you soon!! -|c| Maitre Miltank|C H A N S E Y -|c| QuagGod|GETTEM CRIME -|c| lordkaelros|So now where does this end lol -|c| QuagGod|CHANS HYPE -|c| LifeisDANK|SMOKE AFTER OU WIN -|c| waifu rosalina|I LOADED IT -|c| waifu rosalina|YES -|c| CriclesAreRound|C H A N S E Y -|c| Fryerstarter|Crime♥ forfeited. -|c| Fryerstarter|Crime♥ forfeited. -|c|★CHEF BOY4RDEEZNUTS|CHARIZARD YOU THE REAL MVP -|c| Fryerstarter|y/n -|choice|switch 6|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|73/363 -|cant|p2a: Chansey|par -| -|-heal|p1a: U Jelly Bruh?|95/363|[from] item: Black Sludge -|turn|1003 -|c| CriclesAreRound|C H A N S E Y -|c| Kyorem|para hax -|c| Joshisgayasfuck|frailoldman just needs penis in his mouth -|c| PI EddyChomp|CONGRATS ON HITTING 1003 TURNS ON POKEMON SHOWDOWN!!! -|c| Gaussfield|charizard knows what's up -|c| waifu rosalina|HOW DO THESE TEAMS DEAL FUCKING DAMAGE HELLO -|choice|switch 6|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Chansey|Seismic Toss|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|1004 -|c| lordkaelros|They don't lol -|c| CriclesAreRound|chansey is my hero(second hero aster lando-t) -|c| PI EddyChomp|Lol -|c| LifeisDANK|!! -|c| TheCanadianWifier|HEEEEY -|c| Nortellaz|Alright! -|c| lordkaelros|Why do you think we're at 1004 -|c| waifu rosalina|how do either of these teams -|c| GiraGoomy|! -|c| QuagGod|waifu rosalina they would if they had enuff pp -|c| QuagGod|after -|c| waifu rosalina|break thru -|c|★CHEF BOY4RDEEZNUTS|AYYYYYY LMAO -|c| quay4|**2000 hype?** -|c| Nortellaz|Rapid Spin kill! -|c| CoolSwag2015|rip seismic toss -|c| TheCanadianWifier|back to tenta and a kill is had -|c| CriclesAreRound|C H A N S E Y -|c| waifu rosalina|a substitute -|c| No 1 Machop Fan|what's the record for longest match? -|c| QuagGod|ONE THOUSAND TURNS HYPE -|c|★Crime♥|omg guys stop -|c| LifeisDANK|this is the record -|c| Kuronachan|20 to go -|c| Maitre Miltank|How long does this match last ? -|c| Zenadark|when you begin this match ? -|c| Joshisgayasfuck|you stop -|c| Kuronachan|20 to go -|c|★Crime♥|thats not funny! -|c| Zenadark|Crime -|c| LifeisDANK|CRIME iLY -|c| PI EddyChomp|CHANSEY SWEEP, CHANSEY SWEEP, CHANSEY SWEEP -|c| QuagGod|GO CRIME -|c| QuagGod|ILY -|c| ZzamanN|**NICE B8 M8** -|c| Gaussfield|wow -|c| Nortellaz|Crime, if you don't wanna see, just ignore spectators -|c| PI EddyChomp|GO CRIME -|c| charizard8888|Record Wreckers -|c|★Crime♥|why so much pressure for a girl? how sad -|c| ZzamanN|**8/8** -|c| Gaussfield|stall can literally do nothing -|c| Gaussfield|just recover -|c| CriclesAreRound|7000 approx is the longest match -|c| Kuronachan|crime -|c| quay4|**this is more livly than any room** -|c| PI EddyChomp|WIN IT FOR US -|c| Kuronachan|is my waifu -|c| Maitre Miltank|**How long does this match last ?** -|c| gorry oak|i'm a girl too -|c| Maitre Miltank|**How long does this match last ?** -|c| Maitre Miltank|**How long does this match last ?** -|c| Maitre Miltank|**How long does this match last ?** -|c| Maitre Miltank|**How long does this match last ?** -|c| Zenadark|crime when do you begin this match ? -|c| CoolSwag2015|~~Did anyone else notice that crime for so much support after she said that she was a girl?~~ -|c|★Crime♥|7 hours game -|c| Joshisgayasfuck|1024 turns fuck man chill -|c|★CHEF BOY4RDEEZNUTS|DEEEEEEEEEEEEEZ NUTSSSSSSSSSS -|c| quay4|**100000000000000000 year** -|c|★Crime♥|6 hours and 24 mins -|c| PyoroLoli|goteem -|c| LifeisDANK|LETS GET THIS GOIN -|c|★CHEF BOY4RDEEZNUTS|HAH GOTTEM -|c| X-Pertti|how long does it take to load up this match :D -|c| lordkaelros|Wait, Crime's a gril? -|c| Maitre Miltank|ahhh nice -|c| travisty1|Can you guys actually try and win? -|c| Nortellaz|Crime's not a girl. No one ever says she's a girl on PS. -|c| CriclesAreRound|C H A N S E Y -|c| icyee|well done guys -|c| TheCanadianWifier|WAIT, girls exist? -|c|★Crime♥|half PS knows me from skype lol -|c| CoolSwag2015|loooooool -|c| CroppedPorn|someone explain to me why that chasey won't just switch out -|c| mitchisgaye|crime has been losing for a while, and people tend to back the underdog -|c| StAlRuth|they're trying to not lose, if that counts -|c| Rath111|-.- -|c| CriclesAreRound|1024 incoming -|c| Kuronachan|crime is true gorge forman grill -|c| waifu rosalina|i think so -|c| CriclesAreRound|C H A N S E Y -|c| CroppedPorn|someone explain to me why that chasey won't just switch out -|c| waifu rosalina|tcw -|c| Delibird=Santa|what is a girl -|choice|switch 6|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|95/363 -|move|p2a: Chansey|Toxic|p1a: U Jelly Bruh? -|-immune|p1a: U Jelly Bruh?|[msg] -| -|-heal|p1a: U Jelly Bruh?|117/363|[from] item: Black Sludge -|turn|1005 -|c| charizard8888|30 Secs left -|c| LifeisDANK|I'm a girl but ppl usually assume ima dude. prolly cause of name ;0 -|c| CroppedPorn|someone explain to me why that chasey won't just switch out -|c| QuagGod|grils are nice -|choice|move 4|move 2 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Chansey -|-damage|p2a: Chansey|37/642 par -|move|p2a: Chansey|Toxic|p1a: U Jelly Bruh? -|-immune|p1a: U Jelly Bruh?|[msg] -| -|-heal|p1a: U Jelly Bruh?|139/363|[from] item: Black Sludge -|turn|1006 -|c| CroppedPorn|someone explain to me why that chasey won't just switch out -|c| Maitre Miltank|OMG -|c| LifeisDANK|I like grills too -|c| charizard8888|**WE WON** -|c| Kuronachan|she makes a mean toastie -|c| Daze-Senpai|wtf -|choice|move 4|switch 5 -| -|switch|p2a: Skarmory|Skarmory, F|80/334 -|-damage|p2a: Skarmory|39/334|[from] Stealth Rock -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|36/334 -| -|-heal|p1a: U Jelly Bruh?|161/363|[from] item: Black Sludge -|turn|1007 -|c| Cryolite|stealth rocks -|c| charizard8888|YAY -|c| charizard8888|YAY -|c| charizard8888|YAY -|c| charizard8888|YAY -|c| charizard8888|YAY -|c| charizard8888|YAY -|c| charizard8888|YAY -|c| QuagGod|AYY -|c|★Crime♥|skarmory in action! -|c| Cryolite|thats gg -|c| No 1 Machop Fan|that's the end of Chansey -|c| Cryolite|3 mons die on switch -|c| TheCanadianWifier|BUM BUM BUM, ANOTHER ONE BITES THE DUST -|choice|switch 3|move 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|303/403 -|move|p2a: Skarmory|Defog|p1a: TheMoreYouKnow -|-unboost|p1a: TheMoreYouKnow|evasion|1 -|-sideend|p2: Crime♥|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|-heal|p1a: TheMoreYouKnow|328/403|[from] item: Leftovers -|turn|1008 -|c| waifu rosalina|LOL -|c| lordkaelros|chancey, you will be missed -|c| No 1 Machop Fan|nvm -|c| CriclesAreRound|S K A R M OR Y -|c| PI EddyChomp|YES -|c| Kyorem|no its not -|c| Rath111|lmao -|c|★Crime♥|its not the end of chansey -|c| Kuronachan|THE STEALTH COCKS ARE GONE -|c|★CHEF BOY4RDEEZNUTS|ROCKS ARE HERE TO STAY BITCHES -|c| TheCanadianWifier|anything below 12% is dead -|c| Kyorem|CHANSEY WE LIVIN -|c|★Crime♥|!! -|c| GiraGoomy|rocks jirachi -|c| TheCanadianWifier|yaaaaay -|c| Kuronachan|END OF AN ERA -|c| QuagGod|S K A R M O R Y -|c|★Crime♥|BACK TO CHANSEY!!! -|c| CriclesAreRound|S K A R M O R Y -|c| LifeisDANK|AYy -|c| trolleeee troll|8================D -|c| CoolSwag2015|rocks are coming back now rip -|c| PI EddyChomp|HO CHANSEY -|c| hey i'm pikachu|REVIVE FLORGES -|c|★CHEF BOY4RDEEZNUTS|NO MOAR DEFOGGGGG -|c| QuagGod|**what if gliscor wasn't kill??** -|c| hey i'm pikachu|INSTEAD -|c| PI EddyChomp|GO CHANSEY -|c| Kuronachan|and so we enjoyed peace for two more turns -|c| trolleeee troll|spoiler: 8==================D -|c| BayFence|now this battle is 5-3 -|c| Nortellaz|OK, I change my mind: Snarky Puppy's getting a bit boring now. -|c|★Crime♥|chansey or heatran -|c| No 1 Machop Fan|now I see why we have mods in this battle -|c|★CHEF BOY4RDEEZNUTS|SNARKY PUPPY IS NEVER BORING -|c| CoolSwag2015|this battle is <3 -|c| Cryolite|tran -|c| CriclesAreRound|S K A R M O R Y -|c| Rath111|tran -|c| Kuronachan|heatran -|c| lordkaelros|Sacrilege -|c| CriclesAreRound|S K A R M O R Y -|c| Onecronomicon|Mother of god -|c| Kuronachan|it's suffered from rocks -|c| CriclesAreRound|S K A R M O R Y -|c| waifu rosalina|i wish this was like a tour battle -|c| Kuronachan|for too long -|c| PI EddyChomp|LOOK -|c| The Suicoon|Snarky Puppy is amazing music the hell -|c| waifu rosalina|a roomtour -|c| CoolSwag2015|lol -|c| Kuronachan|let it have this moment -|choice|move 4|switch 6 -| -|switch|p2a: Heatran|Heatran, F, shiny|208/386 par -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Heatran -|-sidestart|p2: Crime♥|move: Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|353/403|[from] item: Leftovers -|-heal|p2a: Heatran|232/386 par|[from] item: Leftovers -|turn|1009 -|c| lordkaelros|Either way, it's your mind -|c| TheCanadianWifier|lol a room tour -|c| PI EddyChomp|CRAZINESS -|c| Nortellaz|Sorry guys :'( -|c| CriclesAreRound|lol if this was a tour battle... -|c| CoolSwag2015|if this was r1 of a roomtour -|c| Kuronachan|GO HEATRAN -|c| QuagGod|H E A T R A N -|c| No 1 Machop Fan|as I was saying... -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| Rath111|lol -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| lordkaelros|I'm not a fan of ween eithe -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -|c| Onecronomicon|lol -|c| charizard8888|**THAT's WHAT I AM TALKIN' ABOUT** -charizard8888 was muted by Former Hope for 7 minutes. -|unlink|charizard8888 -|c| No 1 Machop Fan|end of Chansey -|c|★Crime♥|lol -|c| CoolSwag2015|now 3 mons are RIP to rocks -|c| lordkaelros|kek -|c| CoolSwag2015|llol -|c| QuagGod|gottem -|c| lordkaelros|RIP -|c| CriclesAreRound|H E A T R A N -|c|★Crime♥|end of chansey -|c|★Crime♥|;( -|c| QuagGod|lmfao -|c| CriclesAreRound|H E A T R A N -|c| Dual Screens Mamo|RIP -|c| CriclesAreRound|H E A T R A N -|c|★CHEF BOY4RDEEZNUTS|HAH GOTTEM -|c| fwehaw5UH5AWETHA|VI KA -|choice|switch 4|move 1 -| -|switch|p1a: Fatty|Chansey, F|410/642 -|move|p2a: Heatran|Lava Plume|p1a: Fatty -|-damage|p1a: Fatty|352/642 -|-status|p1a: Fatty|brn -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|-damage|p1a: Fatty|272/642 brn|[from] brn -|turn|1010 -|c| LifeisDANK|its ok bby -|c|@Former Hope|Go wild, but don't spam please -|c| CriclesAreRound|H E A T R A N -|c| Cryolite|l0l -|c| QuagGod|rip chansey :( -|c| QuagGod|but its ok -|c| fwehaw5UH5AWETHA|BURN -|c| StAlRuth|THE BURRRNNN -|c| lordkaelros|Out of plums -|c| PI EddyChomp|**HEATRAN SWEEP HEATRAN SWEEP** -|c| Gaussfield|SICK BURN -|choice|switch 3|move 2 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|161/363 -|move|p2a: Heatran|Roar|p1a: U Jelly Bruh? -|drag|p1a: TheMoreYouKnow|Jirachi|353/403 -| -|-heal|p1a: TheMoreYouKnow|378/403|[from] item: Leftovers -|-heal|p2a: Heatran|280/386 par|[from] item: Leftovers -|turn|1011 -|c| QuagGod|bcoz we gon be alllllright -|c| Nortellaz|Time to turn on guys I actually like instead <3 -|c| Cryolite|4 mons outta pp or die on switch now -|c| PI EddyChomp|BURN BABY BURN -|c| No 1 Machop Fan|AND IT GETS THE BUUUUURRRRRNNN! :p -|c| TheCanadianWifier|WTF THIS STILL HAD A LAVA PLUME LEFT? -|c| CoolSwag2015|**RIP Florges Chansey and Skarmory** -|c| CriclesAreRound|H E A T R A N -|c| CriclesAreRound|H E A T R A N -|c| Kyorem|STRUGGLE -|c| lordkaelros|Struggle time bois -|c| Cryolite|just coba and slowbro left -|c| StAlRuth|tran's OUTTA PP NOW BOIZ -|c| CriclesAreRound|H E A T R A N -|c| hey i'm pikachu|END THIS ZAREL -|c| CriclesAreRound|H E A T R A N -|c| Honoka Kurai|best battle ever -|c| Kuronachan|anyone here remember when there was a transformers manga where little girls kissed transformers to give them power? it was weird -|c| Honoka Kurai|by far -|c|★Crime♥|guyss -|c|★Crime♥|i still have 6 pokemons left! -|c| CriclesAreRound|H E A T R A N -|c| QuagGod|kurona thats wierd -|c| Rath111|30 seconds -|c| BayFence|now u have to use slowbro pp y/y -|c| Rath111|left -|c| CoolSwag2015|chef wins now tbh -|c| TheCanadianWifier|indeed crime ! -|choice|switch 4|switch 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|161/363 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|183/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1012 -|c|★CHEF BOY4RDEEZNUTS|CRIME HALF OF YOUR TEAM DIES TO ROCKS -|c| CoolSwag2015|Crime, technically its 3 -|c| TheCanadianWifier|but you still lose :( -|c| The Mighty Ho|&s& -|c| QuagGod|**holy fuck turn off timer** -|c| Kuronachan|12 turns -|c| waifu rosalina|welp -|c| Kuronachan|it's gonna happen -|choice|switch 3|move 2 -| -|switch|p1a: Fatty|Chansey, F|272/642 -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|1013 -|c| CoolSwag2015|Kuronachan -|c|+Frizy|CoolSwag2015: chef wins now tbh -|c| CoolSwag2015|it doesnt end at 1024 -|c|+Frizy|he won 300 turns ago bro -|c| CoolSwag2015|ik -|c| TheCanadianWifier|lol Frizy -|c| The Mighty Ho|*s* -|c| PI EddyChomp|SEE YOU ALL TOMORROW -|choice|switch 5|move 2 -| -|switch|p1a: Redbull|Clefable, M|297/393 tox -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-heal|p1a: Redbull|321/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|297/393 tox|[from] psn -|-damage|p2a: Slowbro|201/394 tox|[from] psn -|turn|1014 -|c| Kuronachan|heresy -|c| PI EddyChomp|BYE!!! -|c| TheCanadianWifier|you are correct tho -|c| TheCanadianWifier|:] -|c| PI EddyChomp|CONGRATS -|c| Kuronachan|non-believer -|c| lordkaelros|I will see this through to the end -|c| Kuronachan|satanist -|c| hey i'm pikachu|finally -|c| hey i'm pikachu|the wincon -|c| No 1 Machop Fan|Slowbro knows how to be conservative -|c| CoolSwag2015|its over -|c| The Mighty Ho|**O** -|c| breloomiswaifu|wow i gotta go get some lottery -|c| Cryolite|how much pp does cobalion have left -|c| hey i'm pikachu|has arrived -|c| Ed✔️|gg -|c| TheCanadianWifier|Frizy, aren't you super veteran on here? Voice from like 2012? -|c| kyogre518|most my matches r under 20 turns -|c| No 1 Machop Fan|it's probably the only Pokémon with at least 1 PP in all of its moves! -|c| kyogre518|rofl -|c| Kuronachan|10 turns -|c| TheCanadianWifier|i remember seeing your name before -|choice|move 3|move 4 -| -|move|p1a: Redbull|Wish|p1a: Redbull -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 tox -| -|-heal|p1a: Redbull|321/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|273/393 tox|[from] psn -|-damage|p2a: Slowbro|298/394 tox|[from] psn -|turn|1015 -|c|★CHEF BOY4RDEEZNUTS|COB ONLY HAS 1 SWITCH IN -|c| breloomiswaifu|i predicted 400 turns ago this would end at 1100 -|c| lordkaelros|Clef has tons of pp -|c| QuagGod|dont worry we'll make it to turn 1024 -|c| Enzonana|LOL -|c|+Frizy|i used to be a global mod -|c| No 1 Machop Fan|"probably" -|c|+Frizy|ive been on smogon since 09 -|choice|switch 5|move 2 -| -|switch|p1a: Fatty|Chansey, F|272/642 -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-heal|p1a: Fatty|468/642|[from] move: Wish|[wisher] Redbull -|-damage|p2a: Slowbro|178/394 tox|[from] psn -|turn|1016 -|c| QuagGod|vibe to this and hope we make it for 9 more turns https://www.youtube.com/watch?v=Z938ya2fbPo -|c| CoolSwag2015|when this ends ill be sure to screenshot and save to favorites -|c| waifu rosalina|same xd -|c| Kuronachan|8 -|choice|switch 5|move 4 -| -|switch|p1a: Redbull|Clefable, M|273/393 tox -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|375/394 tox -| -|-heal|p1a: Redbull|297/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|273/393 tox|[from] psn -|-damage|p2a: Slowbro|231/394 tox|[from] psn -|turn|1017 -|c| QuagGod|7 more hnnnn -|c| Kuronachan|7 -|c| sancnea|redbull lol -|c| waifu rosalina|I really really dont understand -|c| sancnea|never saw that name -|c| waifu rosalina|how either of these teams -|c| waifu rosalina|break the move called substitute -|choice|switch 5|switch 3 -| -|switch|p1a: Fatty|Chansey, F|468/642 -|switch|p2a: Heatran|Heatran, F, shiny|280/386 par -|-damage|p2a: Heatran|232/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|256/386 par|[from] item: Leftovers -|html|
    Fatty is in an endless loop: it isn't losing HP from Struggle.
    If all active Pokémon go in an endless loop, Endless Battle Clause will activate.
    -|turn|1018 -|c| Kuronachan|6 -|c| sancnea|seismic toss -|c| waifu rosalina|LOL -|c| QuagGod|LOL -|c| Kuronachan|OH MY GOD NO -|c| Cryolite|o shit tho -|c| TheCanadianWifier|wtf? -|c| TheCanadianWifier|LOL -|c| CoolSwag2015|loooooooooooool -|c| StAlRuth|wait wat -|c|★Crime♥|lol -|c|+SpaceBass|LOL -|c| waifu rosalina|ITS BACK -|c| Rath111|LMAO -|c| Kuronachan|FATTY IS THE FALSE HERALD -|c| Kyorem|NOOO -|c| QuagGod|LOOOOOOOOOOOOOOOL -|c| Rath111|ROFL -|c| Rath111|CRIME GO -|c| Enzonana|NOOOOOOOOOO -|c| Rath111|YOU CAN DO THIS -|c|★CHEF BOY4RDEEZNUTS|FATTY DA REAL MVP -|c| hey i'm pikachu|RIP FATTY -|c| QuagGod|GO CRIME -|c| The Mighty Ho|**R I P** -|c| QuagGod|YOU GOT THIS -|c| Kudasaii AFK|wtf -|c| Kyorem|CHEF JUST ATTACK -|c| Kudasaii AFK|crime no -|c| CoolSwag2015|LOOOOOOOOOOOOOOOOOOOL RIP FATTY -|c| QuagGod|RIP FATTY -|c| TheCanadianWifier|CRIME WTF -|choice|move 1|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|362/394 tox -|-damage|p2a: Slowbro|313/394 tox|[from] Stealth Rock -|-activate|p1a: Fatty|move: Struggle -|move|p1a: Fatty|Struggle|p2a: Slowbro -|-damage|p2a: Slowbro|311/394 tox -|-damage|p1a: Fatty|308/642|[from] recoil -| -|-damage|p2a: Slowbro|287/394 tox|[from] psn -|turn|1019 -|c| TheCanadianWifier|TIMER -|c| Cryolite|exploiting corner cases is the only draw -|c|★Crime♥|sry -|c| hey i'm pikachu|2016-2015 -|c| Kudasaii AFK|move -|c|★Crime♥|i wanna smoke -|c| Kudasaii AFK|move -|c| Kudasaii AFK|please -|c|+Frizy|dude -|c| hey i'm pikachu|rip fatty -|c|+Frizy|you dont need to attack -|c| Kuronachan|5 -|c| QuagGod|https://www.youtube.com/watch?v=Z938ya2fbPo WE GON BE AAAALRIGHT -|c|+Frizy|dont throw...... -|c| QuagGod|pull through crime -|choice|switch 3|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|183/363 -|move|p2a: Slowbro|Toxic|p1a: U Jelly Bruh? -|-immune|p1a: U Jelly Bruh?|[msg] -| -|-heal|p1a: U Jelly Bruh?|205/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|239/394 tox|[from] psn -|turn|1020 -|c| QuagGod|:( -|c| Kudasaii AFK|nooo crime -|c| The Mighty Ho|**THE RECOIL* -|c| Kuronachan|4 -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|230/394 tox -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 tox -| -|-heal|p1a: U Jelly Bruh?|227/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|322/394 tox|[from] psn -|turn|1021 -|c| lordkaelros|kek -|c| Kudasaii AFK|frizy is here rof -|c| Gaussfield|dat rapid spin -|c| Kudasaii AFK|hi frizy -|c| Kuronachan|3 -|c|+Frizy|hi -|c| BayFence|now scald burn -|choice|move 4|move 2 -| -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-singleturn|p2a: Slowbro|Protect -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-activate|p2a: Slowbro|Protect -| -|-heal|p1a: U Jelly Bruh?|249/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|226/394 tox|[from] psn -|turn|1022 -|c| Kuronachan|2 -|c|★Crime♥|WB frizy '' yes the battle still going on '' -|c| StAlRuth|HOW WASN'T FATTY LOSING hp FROM STRUGGLE? -|c| Kudasaii AFK|i just joined the match and the game is still seeking -|c| waifu rosalina|fatty why u break rules :[ -|c| StAlRuth|oops caps -|c| QuagGod|if you gotta smoke but ur 1000+ turn match isnt over yet then we gon be https://www.youtube.com/watch?v=Z938ya2fbPo -|c| SCHEFF|>chef boyo4rdeeznuts -|c| QuagGod|remember that crime c: -|c| Enzonana|Reveal lunar dance chansey -|c| Rath111|crime 60 seconds! -|c| Rath111|D: -|c| The Mighty Ho|**1024* -|c|★CHEF BOY4RDEEZNUTS|HAH GOTTEM -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|218/394 tox -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 tox -| -|-heal|p1a: U Jelly Bruh?|271/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|274/394 tox|[from] psn -|turn|1023 -|c| SCHEFF|ed ur names -|c| SCHEFF|xDDD -|c|~Zarel|CHEF, feel free to just ignore the message, it'll be a tie if Endless Battle Clause activates, anyway -|c| Kuronachan|1 -|c| sancnea|loooooooooo -|c| QuagGod|O SHIT -|c| QuagGod|GETTEM -|c| Rath111|yes, if the endless battle clause enables its a tie -|c|★CHEF BOY4RDEEZNUTS|im down for a tie lol -|c| StAlRuth|how? VGC player here, unfamiliar with how this procs endless battle -|c|~Zarel|and either way, unless your opponent activates Endless Battle Clause, it'll be fine -|c|★Crime♥|lol -|c| sancnea|crime succeeds -|c| Kudasaii AFK|zarel when does endless clause activate -|choice|switch 4|switch 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|378/403 -|switch|p2a: Heatran|Heatran, F, shiny|256/386 par -|-damage|p2a: Heatran|208/386 par|[from] Stealth Rock -| -|-heal|p1a: TheMoreYouKnow|403/403|[from] item: Leftovers -|-heal|p2a: Heatran|232/386 par|[from] item: Leftovers -|turn|1024 -|c| Kuronachan|THUNDERBIRDS ARE GO -|choice|move 4|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: TheMoreYouKnow|Stealth Rock|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1025 -|c|~Zarel|when both pokemon active are in an endless loop -|c| Joshisgayasfuck|do it son -|c| waifu rosalina|hi zarel -|c| StAlRuth|chansey is losing HP from struggle tho -|c| lordkaelros|slowbro, why won't you die man -|choice|switch 4|move 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|271/363 -|move|p2a: Slowbro|Toxic|p1a: U Jelly Bruh? -|-immune|p1a: U Jelly Bruh?|[msg] -| -|-heal|p1a: U Jelly Bruh?|293/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|1026 -|c| Kuronachan|nothing happened -|c| Joshisgayasfuck|what the shit is the turn cap -|c| Kuronachan|everything is a lie -|c| No 1 Machop Fan|I don't see any Endless Battle Clause... -|c| Months Behind|smogon battles are so exciting -|c| Rath111|scroll up to find it -|c| lordkaelros|1024 -|c| Kudasaii AFK|my game is still seeking -|c| StAlRuth|I don't see it going off here tbh -|choice|switch 3|switch 3 -| -|switch|p1a: Fatty|Chansey, F|308/642 -|switch|p2a: Heatran|Heatran, F, shiny|232/386 par -|-damage|p2a: Heatran|184/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|208/386 par|[from] item: Leftovers -|turn|1027 -|c|~Zarel|no, it's switching rather than losing HP from Struggle -|c| lordkaelros|reached -|c| No 1 Machop Fan|XD -|c| lolbro|I still cant see -|c|~Zarel|that's an Endless Battle Clause activation condition -|c| Kudasaii AFK|my game is still seeking -|c| Kudasaii AFK|how many turns so far -|c| StAlRuth|ah -|c| Cryolite|1027 -|c| waifu rosalina|1027 -|c| StAlRuth|ty zarel -|c| Kraytoast|1027 -|c| Zenadark|Can I be global @? -|c| hey i'm pikachu|join pokemon showdown for battles 8 hours long! -|c| zebba|oH MY GOD IT'S STILL GOING -|c| SCHEFF|but he said CHEF -|c| SCHEFF|smh -|choice|switch 3|switch 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|293/363 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|315/363|[from] item: Black Sludge -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1028 -|c| TheCanadianWifier|lmao asking for mods -|c|@Former Hope|You don't merely ask -|c| waifu rosalina|.same -|c| SITUM|mdr zena abrutyi -|c| lolbro|richard :D -|c| sancnea|zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz -|c| CoolSwag2015|this battle is awesome -|c| Zenadark|ok sorry -|c| CoolSwag2015|:^) -|c| SCHEFF|oh wait he noticed ed -|c|@Former Hope|You must offer your soul as well as your neighbors -|c| SCHEFF|:c -|c|+Frizy|zarel can i get mods back -|c| CoolSwag2015|lol -|c| Zenadark|That was a joke. -|c| sancnea|z z z z z z z z z z z z z z z z z -|c| SITUM|abruti* -|c|+Frizy|haunter isnt around anymore so its ok -|choice|switch 6|move 4 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 tox -| -|-damage|p2a: Slowbro|346/394 tox|[from] psn -|turn|1029 -|c| waifu rosalina|tcw i moved to saskatchewan -|choice|switch 6|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|208/386 par -|-damage|p2a: Heatran|160/386 par|[from] Stealth Rock -|switch|p1a: U Jelly Bruh?|Tentacruel, M|315/363 -| -|-heal|p1a: U Jelly Bruh?|337/363|[from] item: Black Sludge -|-heal|p2a: Heatran|184/386 par|[from] item: Leftovers -|turn|1030 -|c| waifu rosalina|in canada -|c| waifu rosalina|xd -|c| Ed✔️|Crime♥ forfeited. -|c| sancnea|z z z z z z z z z z z z -|c| TheCanadianWifier|oh shit nice -|c| Bob the Bro|wtf -|c| charizard8888|Sorry Everyone I am back -|c| waifu rosalina|moved sunday -|choice|switch 3|switch 3 -| -|switch|p1a: Fatty|Chansey, F|308/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1031 -|c| QuagGod|Ed stfu -|c|@Former Hope|You might want to PM him, I doubt he'll see messages in this -|c| waifu rosalina|and all my neighbors get wasted at like 2 am -|c| sancnea|z z z z z z z z z z -|c| TheCanadianWifier|how you liking it so far? -|c| waifu rosalina|like screaming -|c| TheCanadianWifier|oh LOL -|c| charizard8888|1031 -|c| CriclesAreRound|i accidnrlty exited this battleand now waiting for it to reload -|c| CoolSwag2015|lol -|c| charizard8888|and counting -|c| sancnea|z z z z z z z -|c| TheCanadianWifier|i mean what else is there to do in Sask? :P -|c| StAlRuth|gg circlesareround -|c| waifu rosalina|is there any tim hortons -|c| waifu rosalina|around -|c| waifu rosalina|:o -|c|★Crime♥|im smoking -|c| TheCanadianWifier|probably! -|choice|switch 5|move 2 -| -|switch|p1a: Redbull|Clefable, M|273/393 tox -|move|p2a: Slowbro|Protect|p2a: Slowbro -|-fail|p2a: Slowbro -| -|-heal|p1a: Redbull|297/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|273/393 tox|[from] psn -|-damage|p2a: Slowbro|273/394 tox|[from] psn -|turn|1032 -|c| waifu rosalina|haha -|c| RoyHasABigDiglett|is life is dank still here -|c| charizard8888|Stop that right now -|c| SCHEFF|i mean i was here so im pumped about that -|c|★CHEF BOY4RDEEZNUTS|mmm delicious lung cancer -|c| Dual Screens Mamo|last protect :o -|c| No 1 Machop Fan|CriclesAreRound: i accidnrlty exited this battleand now waiting for it to reload -|c| PyoroLoli|adiass hi -|c| sancnea|z -|c| sancnea|z -|c| CriclesAreRound|smoke all day -|c| No 1 Machop Fan|LOL! -|c| sancnea|z -|c|★CHEF BOY4RDEEZNUTS|smokers are jokers kids -|c| sancnea|z -|c| BayFence|clefa sweep -|c| sancnea|z -|choice|switch 4|switch 3 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|switch|p2a: Heatran|Heatran, F, shiny|184/386 par -|-damage|p2a: Heatran|136/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|160/386 par|[from] item: Leftovers -|turn|1033 -|c| SCHEFF|but this battle is too damn long -|c| sancnea|im bored typing zs -|c| charizard8888|zzzz -|c| waifu rosalina|★CHEF BOY4RDEEZNUTS: smokers are jokers kids -|c| waifu rosalina|same -|c| CriclesAreRound|H E A T R A N -|c| lordkaelros|Still no second blood :p -|c| charizard8888|^ -|c| CriclesAreRound|H E A T R A N -|c| CriclesAreRound|H E A T R A N -|c|★Crime♥|guys -|c| CriclesAreRound|H E A T R A N -|c| QuagGod|H E A T R A N -|c| CriclesAreRound|H E A T R A N -|c|★CHEF BOY4RDEEZNUTS|chicks who smoke are nasty -|c| charizard8888|It's lagging vigorously -|c|★Crime♥|i will make a team with blastoise or kingler and get to 2000 turns i promise -|c|★Crime♥|<3 -|choice|switch 4|switch 3 -| -|switch|p1a: Redbull|Clefable, M|273/393 tox -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: Redbull|297/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|273/393 tox|[from] psn -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1034 -|c| CoolSwag2015|rof -|c| TheCanadianWifier|LOL chef -|c|★CHEF BOY4RDEEZNUTS|its true -|c| QuagGod|C R I M E ♥ -|c| CriclesAreRound|S L O W B R O -|c| charizard8888|Rest Talk Suicune -|c| waifu rosalina|what if taylor swift -|c| CriclesAreRound|S L O W B R O -|c| CriclesAreRound|S L O W B R O -|c| waifu rosalina|secretly smokes -|c| CriclesAreRound|S L O W B R O -|c| CriclesAreRound|S L O W B R O -|c| CriclesAreRound|S L O W B R O -|c| CriclesAreRound|S L O W B R O -|c| TheCanadianWifier|yea TS smokes and has the voice she does -|c| QuagGod|if its tobacco i wouldnt hit -|c| TheCanadianWifier|nice joke -|c| charizard8888|Hit with FLING -|c| SCHEFF|ugh how is the battle going its still loading :c -|choice|move 3|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|160/386 par -|-damage|p2a: Heatran|112/386 par|[from] Stealth Rock -|move|p1a: Redbull|Wish|p1a: Redbull -| -|-heal|p1a: Redbull|297/393 tox|[from] item: Leftovers -|-heal|p2a: Heatran|136/386 par|[from] item: Leftovers -|-damage|p1a: Redbull|249/393 tox|[from] psn -|turn|1035 -|c| StAlRuth|even then -|c| waifu rosalina|maybe she has a thing in her throat -|c| charizard8888|FLING THE ITEM -|c| StAlRuth|she'd surely shake it off -|c| waifu rosalina|beautiful voice box -|choice|switch 5|switch 3 -| -|switch|p1a: Fatty|Chansey, F|308/642 -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: Fatty|504/642|[from] move: Wish|[wisher] Redbull -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1036 -|c| PyoroLoli|adiass hi -|c| Kudasaii AFK|im back on turn 1035 -|c| Kudasaii AFK|nice -|c| TheCanadianWifier|nice ! -|c| waifu rosalina|xd -|c| CoolSwag2015|turn 1036 -|c| hey i'm pikachu|gj -|c| CoolSwag2015|kek -|c| No 1 Machop Fan|nice -|c| Kudasaii AFK|1036 -|c| Kudasaii AFK|now the game has loaded -|c| breloomiswaifu|its almost over -|c| Kudasaii AFK|still 5 mons -|c| breloomiswaifu|not -|c| Kudasaii AFK|turn 1036 -|c| hey i'm pikachu|how do people have time -|c| Kudasaii AFK|nice -|c| Kudasaii AFK|nice -|c| hey i'm pikachu|for this -|c| memethany fantango|ez for stall -|c| QuagGod|rof -|c| hey i'm pikachu|lmao -|c| waifu rosalina|gratz sacri' -|c| CriclesAreRound|https://www.youtube.com/watch?v=wWSAI9d3Vxk -|c| hey i'm pikachu|sacri -|choice|switch 3|switch 3 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|337/363 -|switch|p2a: Heatran|Heatran, F, shiny|136/386 par -|-damage|p2a: Heatran|88/386 par|[from] Stealth Rock -| -|-heal|p1a: U Jelly Bruh?|359/363|[from] item: Black Sludge -|-heal|p2a: Heatran|112/386 par|[from] item: Leftovers -|turn|1037 -|c| CoolSwag2015|this ends soon tbh -|c| Kudasaii AFK|can we give crime and chef boy4deez nuts -|c| StAlRuth|I'm on uni break, so I can watch this while thing -|c| Kudasaii AFK|custom avatar -|c| hey i'm pikachu|why is sacri a banned phrase -|c| Kudasaii AFK|for having 1036 turns -|c| waifu rosalina|bc sam -|c| Kudasaii AFK|longest turns -|c| waifu rosalina|banned it -|c| CriclesAreRound|they diserve a custom avatar -|c| StAlRuth|did they beat 4chan? -|choice|switch 5|switch 3 -| -|switch|p1a: Redbull|Clefable, M|249/393 tox -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: Redbull|273/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|249/393 tox|[from] psn -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1038 -|c| waifu rosalina|pif vs Crime -|c|★CHEF BOY4RDEEZNUTS|I WANT THE CHEF BOYARDEE GUY -|c| waifu rosalina|imo -|c|★CHEF BOY4RDEEZNUTS|PLS -|c| QuagGod|lol -|c| Cryolite|fav song ever: https://www.youtube.com/watch?v=okqEVeNqBhc -|choice|move 3|move 4 -| -|move|p1a: Redbull|Wish|p1a: Redbull -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 tox -| -|-heal|p1a: Redbull|273/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|225/393 tox|[from] psn -|-damage|p2a: Slowbro|346/394 tox|[from] psn -|turn|1039 -|c| sancnea|stall is love, stall is life -|c| StAlRuth|no I don't think they've beaten 4chan -|c| QuagGod|remember kids -|c| QuagGod|vote ban manaphy -|c| memethany fantango|is the chef boyardee guy not chef boyardee?| -|c| CriclesAreRound|https://www.youtube.com/watch?v=wWSAI9d3Vxk -|c| QuagGod|kappa -|c| Ed✔️|http://niceme.me/ -|c| No 1 Machop Fan|Decided to switch sides. Now all the turns are loading all over again. GEEZ I'm stupid. -|c|★Crime♥|oke guys -|c|★Crime♥|i smoked -|c| Mentagrill|stop timer omg -|c| Aluminion|why am i lagging -|c|★Crime♥|lets start -|c| charizard8888|See ya -|c| TheCanadianWifier|LOL gj No 1 Machop Fan -|c| Gaussfield|ayyy -|c| waifu rosalina|lol -|c| charizard8888|BYE !! -|choice|switch 3|switch 3 -| -|switch|p1a: Fatty|Chansey, F|504/642 -|switch|p2a: Heatran|Heatran, F, shiny|112/386 par -|-damage|p2a: Heatran|64/386 par|[from] Stealth Rock -| -|-heal|p1a: Fatty|642/642|[from] move: Wish|[wisher] Redbull -|-heal|p2a: Heatran|88/386 par|[from] item: Leftovers -|turn|1040 -|c| Gaussfield|let's go -|c| QuagGod|Crime was it tobacco or cannabis -|c|★CHEF BOY4RDEEZNUTS|ravioli ravioli give me the formuoli -|c|★Crime♥|i already smoked weed this night -|c|★Crime♥|tobacco now -|c|@Former Hope|Crime, what is Slowbro's item? -|c| waifu rosalina|SUBSCRIBE TO THECANADIANWIFIER -|c| CriclesAreRound|C H A N S E Y -|c| TheCanadianWifier|.. -|c| QuagGod|kk :( -|c| CriclesAreRound|C H A N S E Y -|c| CriclesAreRound|C H A N S E Y -|c| CriclesAreRound|C H A N S E Y -|c|★Crime♥|former hope @@ we still have a mega slowbro!!!! -|c| lordkaelros|so there's a one toke limit now -|choice|switch 3|switch 3 -| -|switch|p1a: Redbull|Clefable, M|225/393 tox -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: Redbull|249/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|225/393 tox|[from] psn -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1041 -|c| lordkaelros|what sacrilege -|c| CriclesAreRound|turn of the timer -|c| charizard8888|**366 USERS ARE WATCHING THIS THING** -|c| Amber Torrey|People don't deserve avatars for turn stalling.... -|c|★Crime♥|CHEF wants to go sleep -|c|★CHEF BOY4RDEEZNUTS|OMG GUYS I TELL PPL ON THE INTERNET THAT I SMOKE WEED IM SO COOL -|c|★Crime♥|366? wow -|c| CoolSwag2015|this battle is about to end soon -|c| Rath111|20 seconds -|choice|move 3|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|88/386 par -|-damage|p2a: Heatran|40/386 par|[from] Stealth Rock -|move|p1a: Redbull|Wish|p1a: Redbull -| -|-heal|p1a: Redbull|249/393 tox|[from] item: Leftovers -|-heal|p2a: Heatran|64/386 par|[from] item: Leftovers -|-damage|p1a: Redbull|201/393 tox|[from] psn -|turn|1042 -|c| TheCanadianWifier|xd chef -|c| TheCanadianWifier|chill -|c| QuagGod|CHEF BOY4RDEEZNUTS dont be a lame -|c| lordkaelros|We so cool, bois -|c| Kuronachan|poor babies -|c| Medicham's World|It's not even done loading yet for me -|c| QuagGod|jesus -|c| Kuronachan|go to sleep -|c| CriclesAreRound|this is the biggest room on showdown currently -|c| CoolSwag2015|charizard8888 -|c| CoolSwag2015|did you subtract the users who left from that number? -|choice|move 2|switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|move|p1a: Redbull|Flamethrower|p2a: Slowbro -|-resisted|p2a: Slowbro -|-damage|p2a: Slowbro|308/394 tox -| -|-heal|p1a: Redbull|393/393 tox|[from] move: Wish|[wisher] Redbull -|-damage|p1a: Redbull|321/393 tox|[from] psn -|-damage|p2a: Slowbro|284/394 tox|[from] psn -|turn|1043 -|c| Dual Screens Mamo|AN ATTACK?!?! -|c|★Crime♥|i wanna be the most famous staller to be honest -|c|★Crime♥|;( -|c| CoolSwag2015|lol -|c| QuagGod|lo -|c| QuagGod|*lol -|c| waifu rosalina|i bet mom is looking over the shoulder saying "you can do this honey" -|c| TheCanadianWifier|you're the second most famous -|c| TheCanadianWifier|at this time -|c| CriclesAreRound|flame thrower has 16 pp my god -|c| lordkaelros|lmao -|c| StAlRuth|only 4chan is more popular -|choice|switch 5|switch 4 -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|359/363 -|switch|p2a: Florges|Florges, F|35/360 tox -|-damage|p2a: Florges|0 fnt|[from] Stealth Rock -|faint|p2a: Florges -| -|-heal|p1a: U Jelly Bruh?|363/363|[from] item: Black Sludge -|c|@Former Hope|Are you going to go for 5 pokemon KO in one turn? -|c| Kuronachan|I'm always gonna remember this -|c|★Crime♥|oke guys im really sad -|c| Kuronachan|tbh -|c| TheCanadianWifier|OMG -|c|★Crime♥|omg -|c| TheCanadianWifier|A DEATH -|c| ZzamanN|**AN ENEMY HAS BEEN SLAIN** -|c|★CHEF BOY4RDEEZNUTS|HAH GOTTEM -|c|★Crime♥|florges is dead! -|c| CriclesAreRound|RIP -|c| StAlRuth|http://www.myinstants.com/instant/sad-airhorn-_/ -|c| CoolSwag2015|rip -|c| breloomiswaifu|omg -|c| Shinji Kagawa|dont time out -|choice||switch 4 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|turn|1044 -|c| lordkaelros|SECOND BLOOOD -|c| QuagGod|RIP -|c| TheCanadianWifier|5 - 5 -|c| Kuronachan|SECOND BLOOD -|c| gorry oak|RIP -|c| QuagGod|SECOND BLOOD -|c| QuagGod|;_; -|c| Dual Screens Mamo|SECOND BLOOD -|c|★Crime♥|its 5-5 yet! -|c| No 1 Machop Fan|there we go, I'm back :) -|c|★Crime♥|yay timer off -|c| CriclesAreRound|S L O W B R O -|c| Dual Screens Mamo|BATTLE TIMER IS OFF -|c|★Crime♥|can i pee? -|c| CriclesAreRound|S L O W B R O -|c| CoolSwag2015|chansey dies next switchin -|c| waifu rosalina|8 more kills -|c| CriclesAreRound|S L O W B R O -|c| 1+8=th|oh -|c| waifu rosalina|8 more hours :) -|c| CriclesAreRound|S L O W B R O -|c| 1+8=th|wow -|c| CoolSwag2015|skarm dies next switchin -|c| lordkaelros|Lol he turned it off after you had your smoke -|c| Kuronachan|come on crime this is a psychic type vs a poison type you can win this!!! -|c| lordkaelros|r00d -|c| CoolSwag2015|tran dies after 2 switchins -|c|★Crime♥|im almost peeing in my bed lol battling for 6 hours and 43 mins -|c| TheCanadianWifier|3 -|c|★Crime♥|i cant even get up -|c| CoolSwag2015|coba dies after 2 switchins -|c| waifu rosalina|no 2 -|c| charizard8888|I did Ctrl + F joined CoolSwag2015 -|c| Aluminion|and endless battle cluase activates who wins -|c| CriclesAreRound|rofl -|c| Aluminion|plz answer -|c| QuagGod|bro -|c| waifu rosalina|rocks does 12 to tra -|c| Rath111|it's a tie -|c| waifu rosalina|tran -|c| Aluminion|ok -|c| QuagGod|turn off the FUCKing timer -|c| BayFence|coba die in 4 swithces -|c| No 1 Machop Fan|this is the good part -|c| Kudasaii|dont tie it -|c| QuagGod|pls ;_; -|c| CoolSwag2015|charizard8888 did you subtract the users who left from that number -|c| QuagGod|o nvm -|c| QuagGod|im late -|c| Aluminion|scald burn m8 -|c| TheCanadianWifier|oh yea true 11% -|c| Aluminion|go for it -|c|★CHEF BOY4RDEEZNUTS|CRIME YOU STILL HERE? -|c| CriclesAreRound|i guess both of u forfeit toghether -|c| SolarDestruction|I've had 200+ battles -|c| Aluminion|zarel is here -|c| Amber Torrey|367 joined over 700 left -|c| JacobWorld|hey -|c| Kudasaii|why did zarel turn on timer -|c| Aluminion|wow i didn't know -|c| Rath111|probably peeing -|c| QuagGod|zarel noooo -|c|★Crime♥|yes -|c| charizard8888|why would you subtract -|c| QuagGod|:( -|c| waifu rosalina|requested by zarel -|c| waifu rosalina|damn -|c|★Crime♥|im trying to relax.. -|c|★Crime♥|my eyes are exploding -|c| Kudasaii|poor crime -|c| lordkaelros|'relax' -|c|★CHEF BOY4RDEEZNUTS|30 secs -|c| Kudasaii|this isnt even a serious game -|c| Dual Screens Mamo|OH -|c|~Zarel|okay, fine, have like five minutes to pee -|c| CoolSwag2015|kek timer off now -|c| Enzonana|Zarel aburrido :c -|c|★Crime♥|thanks you zarel! <3 -|c| Rath111|zarel ggave you 5 minute sto pee -|c| Dual Screens Mamo|BASED STAFF -|c| Rath111|go peeeeeeeeeeeeeeeee -|c| Cryolite|zarel the real mvp -|c|★Crime♥|ill be back in 5 ! <3 -|c| Nass-T|Where is chaos -|c| waifu rosalina|LOL -|c| Kudasaii|Zarel the real mvp -|c| Amber Torrey|Wow turning off the timer in a stall war -|c| waifu rosalina|SAME -|c| Enzonana|LOL -|c| TheCanadianWifier|LOOOL 5 more minutes -|c| QuagGod|meloetta king zarel has spoken -|c| waifu rosalina|THATS NOT LONG ENOUGH -|c| laxs|This is like a slave show, who will you bet money on? The mods control them. -|c| Amber Torrey|what kind of bs is that... -|c| waifu rosalina|WHAT IF SHES CONSTIPATED -|c| waifu rosalina|:[ -|c| lordkaelros|gg -|c| Kudasaii|lol laxs thats so deep -|c| Nass-T|I can't even see the battle lmao -|c|★CHEF BOY4RDEEZNUTS|SO WHATS EVERYONES FAV BRAND OF RAVIOLI? -|c| TheCanadianWifier|**turn 1044** - the longest turn in history -|c| Corridor|LAG -|c| CriclesAreRound|S L O W B R O -|c| CoolSwag2015|so chansey dies next switch, skarm dies next switch, tran dies after 2 switchins, coba dies after 2 switchins -|c| Kuronachan|so gracious of you zarel -|c| CoolSwag2015|once all those are gone, slowbro dies eventually to toxic -|c| CoolSwag2015|its gg -|c| lordkaelros|Ravioli has brands? -|c| ZzamanN|Ravioli -|c| ZzamanN|Ravioli -|c| Kudasaii|**turn 2093** -|c| ZzamanN|What's in the pocketoli -|c| Gaussfield|ravioli brand ravioli -|c| Amber Torrey|can't believe they turned off timer -|c| No 1 Machop Fan|commercial break! :p -|c| charizard8888|zzzzzzzzzz -|c| waifu rosalina|why tf are we talking about raviolis -|c| CriclesAreRound|2000 years latter............. -|c| Nass-T|its chef bouardi -|c| waifu rosalina|i could have reqs by now -|c| Amber Torrey|in these kind of fights world events are what break people -|c| waifu rosalina|but instead -|c| No 1 Machop Fan|suddenly I'm tempted to advertise my rail project/campaign -|c| waifu rosalina|im watching this -|c| waifu rosalina|... -|c| Kuronachan|fuck reqs -|c| CoolSwag2015|why did i waste an hour of my life watching this -|c| CoolSwag2015|tbh -|c| charizard8888|**Please Do NOT type /clear** -|c| Kudasaii|LOL COOL SWAG -|c| QuagGod|LOL -|c| charizard8888|or reload it again lol -|c| Rath111|you wasted an hour -|c| Kudasaii|CHARIZARD PLEASE DO NOT USE REVERSE PSYCHOLOGY -|c| Nass-T|It still says Seaking damn I cant see the battle -|c| Rath111|to watch history unfold -|c| Kuronachan|your vote is only one in a sea of many that in the end will not matter -|c| Rath111|this match will be remembers for eons -|c| CriclesAreRound|i dare u reload the page -|c| charizard8888|lol Kudasaii -|c| Aluminion|what about the original troll slowbro -|c| CoolSwag2015|well at least i can screenshot this when it ends. -|c|★CHEF BOY4RDEEZNUTS|TYPES OF NUTS: BOILED, SALTED, ROASTED, ASSORTED, DEEZ!!!! -|c| Aluminion|that game was pretty long -|c| Amber Torrey|never would imagine this battle could get anymore boring -|c| Kudasaii|DEEZ -|c| Gaussfield|deez? -|c| AxeBane|I will remember each and every move that was made in this battle. -|c| Amber Torrey|welp i was wrong -|c| Pyoro(AFK)|deez nutz -|c| Pyoro(AFK)|goteem -|c| JacobWorld|ravioli ravioli give me the formuoli -|c|★CHEF BOY4RDEEZNUTS|HAH GOTTEM -|c| 1+8=th|LOL -|c| Medicham's World|Holy crap what a battle -|c|★Crime♥|im back :3 -|c| CoolSwag2015|instantcena.com -|c| CoolSwag2015|wb -|c| Aluminion|nah chef you don't have nuts -|c|★Crime♥|thank you mod! -|c| Kuronachan|wb -|c|★Crime♥|thanks coolswag! -|c|★CHEF BOY4RDEEZNUTS|LETS DO THIS -|c| CriclesAreRound|DEEEEEEZ NU...C H A N S E Y -|c| lordkaelros|How old are you chef? -|c| QuagGod|AYYYY -|c| QuagGod|GETTEM CRIME -|c|★CHEF BOY4RDEEZNUTS|22 -|c| 1+8=th|this match -|c| 1+8=th|making me lag -|c| 1+8=th|so hard -|c| kyogre518|free lando-i -|c| Aluminion|lol rekt -|c| CoolSwag2015|lol -|c| charizard8888|nice name ^ 1+8 -|c|★Crime♥|are you guys ready to watch again? -|c|★Crime♥|:D -|c| CriclesAreRound|i might as well complete my home work -|c| Rath111|yeaaaaaaaaaah :D -|c| Kudasaii|Nice name 1+8 -|c| Kuronachan|yes -|c|★Crime♥|thanks zarel <3 -|c| Kuronachan|zarel why -|c|★Crime♥|for making me pee -|choice|switch 3|switch 5 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Chansey|Chansey, F|37/642 -|-damage|p2a: Chansey|0 fnt|[from] Stealth Rock -|faint|p2a: Chansey -| -|c| ZzamanN|Zarel, you da real mvp -|c| Kuronachan|JESUS GO -|c| AxeBane|Zarel has had enough of your shit. xD -|c|★CHEF BOY4RDEEZNUTS|RIP -|c| TheCanadianWifier|Guys when the game finally finishes, can we get an official timer? -|c| Pyoro(AFK)|ded -|c| Gaussfield|ih -|c| 1+8=th|Thanks Kuda -|c| Cryolite|5-4 -|c| CoolSwag2015|3rd blood -|c| JacobWorld|bye -|c| CoolSwag2015|!!!! -|c| charizard8888|BYE -|c| Gaussfield|oh. -|c| GiraGoomy|5-4 -|c| Dual Screens Mamo|THIRD DEATH -|c| Gaussfield|R I P -|c| lordkaelros|3rd blood -|c| The Master Bait|He didn't MAKE you pee, he LET you pee. Word usage, young man. -|c| ZzamanN|**AN ENEMY HAS BEEN SLAIN** -|c| lordkaelros|People be a dying na0 -|c| Kudasaii|2 pokemons = 1000 turns -|c| CoolSwag2015|**Third blood** -|c| QuagGod|OMG -|c| Medicham's World|//forcetie y/y -|c| Kudasaii|6 pokemons = 3000 -|c| Kuronachan|NOOOOOOOO -|choice||switch 2 -| -|switch|p2a: Cobalion|Cobalion|46/386 -|-damage|p2a: Cobalion|34/386|[from] Stealth Rock -|turn|1045 -|c| QuagGod|THIRD BLOOD HYPE -|c| Kudasaii|2 pokemons = 1000 -|c| QuagGod|R I P -|c|★Crime♥|coba time -|c|★Crime♥|;o -|c| Kudasaii|6 = 3000 -|c| Kuronachan|MY #TEAMCHANSEY -|c| No 1 Machop Fan|wait, what happened? -|c| Kudasaii|2000 more turns -|c| Gaussfield|AYYY COBA'S LIVIN -|c| No 1 Machop Fan|what's this about peeing? -|c| Kudasaii|this is part 1 of the trilogy -|c| Cryolite|that mons gonna sweep -|c| 1+8=th|OH MAN -|c| TheCanadianWifier|Dude, Coba could sweep -|c| CriclesAreRound|how much does cc do? -|choice|switch 6|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Iron Head|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|247/301 -| -|turn|1046 -|c| Kudasaii|guys i came back from turn 1 what happened -|c| Dual Screens Mamo|this thing still has PP -|c| Kudasaii|i was away -|c| TheCanadianWifier|wth some iron head flinches -|c| MonochromeCloud|What the fuck -|c| Kuronachan|the plays -|c| lordkaelros|Coba Sweep incoming? -|c| Honoka Kurai|best match ever. -|c| laxs|Longest battle= Switch pokemon -|c| CoolSwag2015|7 iron head flinches to win -|c| travisty1|GO FOR REST -|c| CoolSwag2015|ez -|c| laxs|Have fun -|choice|switch 4|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|403/403 -|move|p2a: Cobalion|Iron Head|p1a: TheMoreYouKnow -|-resisted|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|359/403 -| -|-heal|p1a: TheMoreYouKnow|384/403|[from] item: Leftovers -|turn|1047 -|c| Cryolite|its not gonna happen -|c| Cryolite|rach can twave -|c| CoolSwag2015|gg -|c| TheCanadianWifier|rip -|c| 1+8=th|i wonder how long will it take it to complete seeking -|choice|switch 4|move 2 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|247/301 -|move|p2a: Cobalion|Iron Head|p1a: I <3 Stall -|-damage|p1a: I <3 Stall|190/301 -| -|turn|1048 -|c| BayFence|battle for +30 points :3 -|c|★Crime♥|1100 turns ;'( -|c| Kuronachan|this is so fucking tense rn -|c| CriclesAreRound|1050 hype!!!!!!!!! -|c| QuagGod|^ -|c| Kudasaii|BayFence u r wrong -|c| Kudasaii|whoever wins gets -|c| Gaussfield|swap into redbull :V -|c| TheCanadianWifier|1069 y/n -|choice|move 4|move 1 -| -|move|p2a: Cobalion|Close Combat|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -|move|p1a: I <3 Stall|Recover|p1a: I <3 Stall -|-heal|p1a: I <3 Stall|301/301 -| -|turn|1049 -|c| Kudasaii|this same elo as the amount of turns -|c| The ✔️erlisify|Click the x already -|c| Kuronachan|NGHNGIOWP -|c| CriclesAreRound|battle for +7 points -|c| Aluminion|cobalion can switch out, switch in, switch out again, switch in again then it has to battle to death -|c| Kudasaii|reach 1069 -|c| Kuronachan|NO -|c| waifu rosalina|fuck i left now i gotta seek again fuck -|c| Kudasaii|reach 1068 -|choice|switch 4|move 1 -| -|switch|p1a: TheMoreYouKnow|Jirachi|384/403 -|move|p2a: Cobalion|Close Combat|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|249/403 -|-unboost|p2a: Cobalion|def|1 -|-unboost|p2a: Cobalion|spd|1 -| -|-heal|p1a: TheMoreYouKnow|274/403|[from] item: Leftovers -|turn|1050 -|c| Kudasaii|**1069 please** -|c| Gaussfield|ohboy -|c| QuagGod|^ -|c|★Crime♥|lol -|c| StAlRuth|http://www.myinstants.com/instant/sad-airhorn-_/ -|c| Myahri|yep -|c| CriclesAreRound|69! -|choice|switch 4|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Close Combat|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|1051 -|c| Rath111|oh -|c| Cryolite|yeah this is over -|c| lordkaelros|4 more atks left -|c|★Crime♥|im soooo sad. -|c| CriclesAreRound|6 roars -|c|★Crime♥|lmao -|c| Gaussfield|ppbooooooooys -|c| megaslowbro1|hi -|c| Fryerstarter|HEY CHEF -|c| Aluminion|i have a stall team with slowbro, amoonguss and tornadus -|c| Fryerstarter|i heard he 6-0'd you. -|c| Dual Screens Mamo|oml -|c| TheCanadianWifier|so sad? http://www.myinstants.com/instant/sad-airhorn-_/ -|c| Aluminion|all with regen -|c| CriclesAreRound|crime and chef need custom avatars -|c| Dual Screens Mamo|roar will get bounced and somethign will die to rocks -|c| Aluminion|#get rekt -|choice|switch 4|move 1 -| -|switch|p1a: TheMoreYouKnow|Jirachi|274/403 -|move|p2a: Cobalion|Close Combat|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|135/403 -|-unboost|p2a: Cobalion|def|1 -|-unboost|p2a: Cobalion|spd|1 -| -|-heal|p1a: TheMoreYouKnow|160/403|[from] item: Leftovers -|turn|1052 -|c| Kudasaii|Give crime and chef custom avatars -|c| Dual Screens Mamo|OH -|c| lordkaelros|played -|c|★CHEF BOY4RDEEZNUTS|Mono regen team anyone? -|c| Gaussfield|geezus -|c| Kudasaii|why do u have a custom -|c| Gaussfield|the damage -|c| Kudasaii|i* -|c| No 1 Machop Fan|nup -|choice|move 2|move 2 -| -|move|p2a: Cobalion|Iron Head|p1a: TheMoreYouKnow -|-resisted|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|115/403 -|cant|p1a: TheMoreYouKnow|flinch -| -|-heal|p1a: TheMoreYouKnow|140/403|[from] item: Leftovers -|turn|1053 -|c| No 1 Machop Fan|only one CC left -|c| Dual Screens Mamo|OH -|c| Rath111|OH SHIT -|c| The Mighty Ho|OH -|choice|switch 4|move 1 -| -|switch|p1a: I <3 Stall|Sableye-Mega, M|301/301 -|move|p2a: Cobalion|Close Combat|p1a: I <3 Stall -|-immune|p1a: I <3 Stall|[msg] -| -|turn|1054 -|c| Aluminion|omg -|c| The Master Bait|To be fair, Crime deserved it after dicking around with switches so long ;) -|c| Amber Torrey|playing a stall match is not custom avatar worthy... -|c| Gaussfield|JIRACHI WAS FLINCHED -|c| Gaussfield|HOOOOOOOOOOOO -|c| lordkaelros|played -|choice|switch 4|move 2 -| -|switch|p1a: TheMoreYouKnow|Jirachi|140/403 -|move|p2a: Cobalion|Iron Head|p1a: TheMoreYouKnow -|-resisted|p1a: TheMoreYouKnow -|-damage|p1a: TheMoreYouKnow|94/403 -| -|-heal|p1a: TheMoreYouKnow|119/403|[from] item: Leftovers -|turn|1055 -|c| CriclesAreRound|iron 1069 pls chef -|c| Kuronachan|i cant do this -|c| Dual Screens Mamo|RIP -|c| The Master Bait|You reap what you sow ;) -|c| Aluminion|lol -|c| Kuronachan|reveal -|c| Kudasaii|1111 -|c| StAlRuth|rip -|c| Kuronachan|the hidden power ground -|c| Kudasaii|if god is real -|c| Kudasaii|1111 -|c| 1+8=th|Finally -|c| Kudasaii|turns imo -|c| 1+8=th|loaded -|c| Kudasaii|make it 1111 -|c| quay4|still going -|c| Kudasaii|lol -|c| lordkaelros|It's gg for crime -|c| waifu rosalina|mu fucking computer crashed 4 times now -|c| Medicham's World|Just a question of time, crime is gonna lose -|c| TheCanadianWifier|1100 is i guess possible -|c| waifu rosalina|.... -|c|★Crime♥|=( -|c| TheCanadianWifier|if played perfectly -|c| Kudasaii|1111 is a good number -|c| QuagGod|1069 turns HYPE -|c| breloomiswaifu|1100 -|c| Kudasaii|1111 -|c| Kudasaii|1111 -|c| Kudasaii|all 1's -|c| lordkaelros|I like 1111 -|c| Aluminion|crime is gonna lose to the rocks in the end -|c| Kudasaii|to celberate 20111 -|c| 1+8=th|Yes -|c| Kudasaii|2011* -|c| CriclesAreRound|1069 lets go -|c|@Former Hope|Those stealthy rocks -|c| Kudasaii|this game is so long its history -|c|★Crime♥|Kudasaii i gave you a free win in cc 1 vs 1 when you were in top 3 <3 -|c| StAlRuth|sneaky pebbles -|c| waifu rosalina|stealth rockies -|c| Rath111|try to let coba live -|c| Gaussfield|B E L I E V E -|c| Rath111|switch to slowbro -|c|★CHEF BOY4RDEEZNUTS|why are they stealthy -|c| AxeBane|The stealthiest of rocks. -|c| Rath111|imo -|c|★CHEF BOY4RDEEZNUTS|i can see them -|c| Kudasaii|Really Crime? -|c| Kudasaii|<3 -|choice|move 2|move 4 -| -|move|p1a: TheMoreYouKnow|Thunder Wave|p2a: Cobalion -|-status|p2a: Cobalion|par -|cant|p2a: Cobalion|par -| -|-heal|p1a: TheMoreYouKnow|144/403|[from] item: Leftovers -|turn|1056 -|c| Kudasaii|i forgot -|c| Kudasaii|on an alt? -|c|★Crime♥|yuh ;3 -|c| Kudasaii|:3 -|c| CriclesAreRound|S L O W B R O -|c| AxeBane|Do not question the rocks! -|c| Kuronachan|well -|c| CriclesAreRound|S L O W B R O -|c| Kuronachan|thats just insult to injury -|c| Kudasaii|ty crime <3 -|c| AxeBane|They know more than you ever will! >:/ -|c| waifu rosalina|who cares about cc :[ -|c| StAlRuth|this just delays the pp stallfest -|c| The Master Bait|Better pray for perennial paralysis -|c| CriclesAreRound|C O B A L I O N -|c|★Crime♥|my names were I AM NOT STALLING, and Staller Jess and half PS saw me on skype or so xD -|c| TheCanadianWifier|Once again proving, Stealth Rocks truly _are_ the best move in the game! Thanks, Smogon! -|c| CriclesAreRound|next suspect stall -|c| Kudasaii|Kek -|choice|switch 5|move 4 -| -|switch|p1a: Redbull|Clefable, M|321/393 tox -|move|p2a: Cobalion|Roar|p1a: Redbull -|drag|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -| -|turn|1057 -|c| CriclesAreRound|C O B A L I O N -|c| lordkaelros|Matte Kudasai? -|c| CriclesAreRound|C O B A L I O N -|c| lordkaelros|Or plain Kudasai? -|c| Kudasaii|Mate. -|c|★CHEF BOY4RDEEZNUTS|RAPID SPIN LETS GO -|c| CriclesAreRound|C O B A L I O N -|c|@Former Hope|Chef, here's the rather sad thing. I think those rocks have done more damage than your entire team combined -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Cobalion -|-resisted|p2a: Cobalion -|-damage|p2a: Cobalion|28/386 par -|move|p2a: Cobalion|Roar|p1a: U Jelly Bruh? -|drag|p1a: Redbull|Clefable, M|321/393 tox -| -|-heal|p1a: Redbull|345/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|321/393 tox|[from] psn -|turn|1058 -|c| CriclesAreRound|C O B A L I O N -|c| lordkaelros|That is the question -|c| Gaussfield|1 % -|c| Rath111|oh shit -|c| Kuronachan|yeah that's right -|c| Rath111|1% -|c| Kuronachan|chip away -|c| The Master Bait|Matte Kudasai - the worst song on Discipline. -|c| CoolSwag2015|former hope, so true -|c| Gaussfield|O N E P E R C E N T -|c| PluieDeLeftiez|endure -|c| Kudasaii|no 1069? -|choice|move 1|move 4 -| -|move|p1a: Redbull|Moonblast|p2a: Cobalion -|-damage|p2a: Cobalion|0 fnt -|faint|p2a: Cobalion -| -|-heal|p1a: Redbull|345/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|297/393 tox|[from] psn -|c| JacobWorld|my laptop can't take this anymore -|c| Kudasaii|no 1079? -|c| Pyoro(AFK)|ded -|c| Gaussfield|oh -|c| Kudasaii|no 1111? -|c| JacobWorld|bang -|c| lordkaelros|I agree -|c| CoolSwag2015|its over now -|c| CoolSwag2015|!!! -|c| Honoka Kurai|1069 -|c| Kuronachan|it's all ogre -|c| Honoka Kurai|(y) -|c| Dual Screens Mamo|OH -|c| PluieDeLeftiez|reveal hp ground -|c| QuagGod|4th blood -|c| ZzamanN|**TRIPLE KILL** -|c| Gaussfield|it's not over -|c| waifu rosalina|why does gyarados just beat both of these teams -|c| CriclesAreRound|RIP -|c|★Crime♥|its not over yet! -|c| QuagGod|its all ogre *-* -|c| Gaussfield|until it's over -|c|★Crime♥|we still have mega slowbro -|c| StAlRuth|http://www.myinstants.com/instant/mlg-airhorn/ for chef -|c| QuagGod|o -|c| CriclesAreRound|1 0 6 9 -|c| TheCanadianWifier|Former Hope, Oh for sure. The rocks have probably done upwards of 10,000% -|c| CriclesAreRound|1 0 6 9 -|c| QuagGod|C R I M E -|c| TheCanadianWifier|all combined -|c| CriclesAreRound|1 0 6 9 -|c| Frozen Despair|>thousand turns -|c| CriclesAreRound|1 0 6 9 -|c| CoolSwag2015|bro is toxiced -|c| CriclesAreRound|1 0 6 9 -|c| QuagGod|<3 -|c| CoolSwag2015|so rip -|c| CriclesAreRound|1 0 6 9 -|choice||switch 5 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|turn|1059 -|c| CriclesAreRound|1 0 6 9 -|c| CriclesAreRound|1 0 6 9 -|c| CriclesAreRound|1 0 6 9 -|c| CriclesAreRound|1 0 6 9 -CriclesAreRound was muted by Former Hope for 7 minutes. -|unlink|criclesareround -|c| Myahri|how long have you guys been going -|choice|switch 6|switch 3 -| -|switch|p1a: Fatty|Chansey, F|642/642 -|switch|p2a: Heatran|Heatran, F, shiny|64/386 par -|-damage|p2a: Heatran|16/386 par|[from] Stealth Rock -| -|-heal|p2a: Heatran|40/386 par|[from] item: Leftovers -|turn|1060 -|c| StAlRuth|6 hrs + -|c| Medicham's World|lol -|c|★Crime♥|7 hours over 6 mins -|c|@Former Hope|Again, go crazy. Don't spam -|c| CoolSwag2015|go crazy -|c| CoolSwag2015|kek -|c| Kudasaii|we've been playing for 4 hours -|c| CoolSwag2015|kk -|choice|switch 6|switch 3 -| -|switch|p1a: Redbull|Clefable, M|297/393 tox -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -| -|-heal|p1a: Redbull|321/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|297/393 tox|[from] psn -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1061 -|c| CoolSwag2015|**VISIT** instantcena.com -|c| Dual Screens Mamo|TRAN IS DED -|c| CoolSwag2015|:^) -|c| AxeBane|Former throwing out the oxymorons like he just doesn't care. .3. -|c| Sweanger|http://strawpoll.me/6185409/ -|c|★CHEF BOY4RDEEZNUTS|Crime apologies for getting angry earlier lol -|c| Cryolite|now two mons die to switching in -|c| TheCanadianWifier|What would be cool is: if someone could make a script to add up all the damage that Stealth Rock did to Crimes team over the course of 1100 turns -|c| waifu rosalina|coulda gotte pu reqs, uureqs by now -|c| waifu rosalina|:[ -|c|★Crime♥|its okay chef.. -|c| TheCanadianWifier|I'd bet it's close to 10,000% -|c| No 1 Machop Fan|nup, Heatran's done -|choice|move 3|switch 3 -| -|switch|p2a: Heatran|Heatran, F, shiny|40/386 par -|-damage|p2a: Heatran|0 fnt|[from] Stealth Rock -|faint|p2a: Heatran -|move|p1a: Redbull|Wish|p1a: Redbull -| -|-heal|p1a: Redbull|321/393 tox|[from] item: Leftovers -|-damage|p1a: Redbull|273/393 tox|[from] psn -|c| CoolSwag2015|GG -|c| Dual Screens Mamo|OH -|c| Honoka Kurai|damn -|c| ZzamanN|**QUADRA KILL** -|c| lordkaelros|And so the team falls like dominoes -|c|★Crime♥|guys im so badddddddd -|c| Kuronachan|goodbye lava turtle friend :( -|c| Gaussfield|i see where this is going -|c| Breaking 2 Chainz|one more -|c| CoolSwag2015|smh crime -|choice||switch 3 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|turn|1062 -|c| Honoka Kurai|gg ma' boy -|c| Dual Screens Mamo|8 more turns -|c| Kuronachan|fifth blood -|c| Dual Screens Mamo|pls -|c| Pyoro(AFK)|ded -|c| The Master Bait|Imagine if Pokemon didn't have pp. -|c| QuagGod|o shit -|c| lordkaelros|Forfeit just before your last pokemon dies please -|c| The Master Bait|Where would we be now? -|c| QuagGod|7 more turns -|choice|switch 5|switch 6 -| -|switch|p1a: TheMoreYouKnow|Jirachi|144/403 -|switch|p2a: Skarmory|Skarmory, F|36/334 -|-damage|p2a: Skarmory|0 fnt|[from] Stealth Rock -|faint|p2a: Skarmory -| -|-heal|p1a: TheMoreYouKnow|340/403|[from] move: Wish|[wisher] Redbull -|-heal|p1a: TheMoreYouKnow|365/403|[from] item: Leftovers -|c| Honoka Kurai|mother of god -|c| breloomiswaifu|go mega -|c| CoolSwag2015|GG -|c| PyoroLoli|ded -|c| No 1 Machop Fan|now Clefable's the conservative one! :o -|c| CoolSwag2015|its over -|c| Kuronachan|sixth blood -|c| Honoka Kurai|G fucking G. -|c| ZzamanN|**PENTAKILL!** -|c|★Crime♥|T_T -|c| lordkaelros|Don't let him end it Crime -|c| laxs|godhatesfags.com -|c| laxs|:) -|c| AxeBane|Finish Him. :o -|c| lordkaelros|Do it on your own terms -|c| Kudasaii|wtf happened to 1069 -|c| lordkaelros|Don't Fear the Reaper -|c| 1+8=th|GG. -|choice||switch 6 -| -|switch|p2a: Slowbro|Slowbro, F|394/394 tox -|-damage|p2a: Slowbro|345/394 tox|[from] Stealth Rock -|turn|1063 -|c| Aluminion|lesson of the day: rapid spin>defog -|c| Kuronachan|1069 is still possible -|c| The Master Bait|Forfeit just before the Toxic kills you. -|c| waifu rosalina|i dont have the mental capacity to play over 100 turns -|c| waifu rosalina|in pokemon -|c| Kudasaii|chef if u /forfeit -|c| StAlRuth|GG -|c| JacobWorld|c'mon 1069 -|c| Kuronachan|it can happen -|c| StAlRuth|F -|c| JacobWorld|c'mon 1069 -|c| StAlRuth|F -|c| TheCanadianWifier|we still love you, Crime. -|c| The Master Bait|Don't Fear the Reaper, baby take my hand -|c| Kuronachan|anything can change! -|c| TheCanadianWifier|Just try and quit smoking ~ -|c| Kudasaii|you're a good man -|c| CoolSwag2015|mfw -|c| Myahri|do 1068 just to troll with everyone -|c| lordkaelros|commit sudoku -|c| Dual Screens Mamo|F to pay respects -|c| The Master Bait|...Sudoku? -|c| Honoka Kurai|go, burn him -|c| Kudasaii|R -|c| Aluminion|scald burn -|c| Kudasaii|F -|c| Dual Screens Mamo|F -|c|★Crime♥|here we go MEGA... -|c| Kudasaii|f -|c| AxeBane|>Sudoku -|c| Honoka Kurai|that will matter. -|c| waifu rosalina|agreed just quit ^^ -|c| 1+8=th|F -|choice|switch 3|move 1 mega -| -|switch|p1a: U Jelly Bruh?|Tentacruel, M|363/363 -|detailschange|p2a: Slowbro|Slowbro-Mega, F -|-mega|p2a: Slowbro|Slowbro|Slowbronite -|move|p2a: Slowbro|Scald|p1a: U Jelly Bruh? -|-resisted|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|323/363 -|-status|p1a: U Jelly Bruh?|brn -| -|-heal|p1a: U Jelly Bruh?|345/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|300/363 brn|[from] brn -|-damage|p2a: Slowbro|321/394 tox|[from] psn -|turn|1064 -|c| Kudasaii|F -|c| Gaussfield|AYYYYYYYYYYYYYY -|c| Kyorem|F -|c| frailoldman|see, girls never win anything -|c| AxeBane|Yes. We must all commit to the puzzle game. -|c| Gaussfield|THE BURN -|c| Kudasaii|F to pay respects -|c| Kuronachan|sudoku is my favourite e-sport -|c| ZzamanN|ayy lmao -|c| Amber Torrey|Yeah i don't respect this... -|c| Rath111|LOL burnt -|c| TheCanadianWifier|LOOOOOOOOOOOOOOOOOOOOOL -|c| The Master Bait|The thing had a Mega Evolution> -|c| CoolSwag2015|burn kek -|c| Honoka Kurai|Ya' see -|c| ZzamanN|nice mega -|c| QuagGod|BURN -|c| Kuronachan|IS THAT A FUCKING MEGA -|c| TheCanadianWifier|after all that -|c| Kudasaii|I like Crime she is cute af -|c| The Master Bait|??? -|c| QuagGod|HYPE IT UP -|c| TheCanadianWifier|the burn -|c| lordkaelros|lol -|c| Kuronachan|IM DED -|c| breloomiswaifu|Oooooh the burn -|c| lordkaelros|ofc it's a mega -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|318/394 tox -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 tox -| -|-heal|p1a: U Jelly Bruh?|322/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|277/363 brn|[from] brn -|-damage|p2a: Slowbro|346/394 tox|[from] psn -|turn|1065 -|c| ZzamanN|That late game mega evolution -|c| Honoka Kurai|1069 -|c| Honoka Kurai|pls -|c| Kyorem|Crime is my fave now -|c| 1+8=th|kuda got a crush -|c| waifu rosalina|f -|c| 1+8=th|:) -|c|★Crime♥|Kyorem <3 -|c|★Crime♥|lel -|c|@Former Hope|One more move -|c| lordkaelros|Crime please forfeiterino :p -|c|@Former Hope|gg wp -|c|★Crime♥|yes Former Hope -|c| Kuronachan|crime is stall waif -|c| Kuronachan|tbh -|c| Gaussfield|crime got the burn in the end -|c| TheCanadianWifier|GG Guys! -|c| JacobWorld|**c'mon 1069** -|c| weird random|ugh -|choice|move 4|move 4 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|343/394 tox -|move|p2a: Slowbro|Slack Off|p2a: Slowbro -|-heal|p2a: Slowbro|394/394 tox -| -|-heal|p1a: U Jelly Bruh?|299/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|254/363 brn|[from] brn -|-damage|p2a: Slowbro|322/394 tox|[from] psn -|turn|1066 -|c| QuagGod|breh -|c| CoolSwag2015|**GG** -|c| StAlRuth|wrap it up, dont forfeit! -|c| QuagGod|4 more turns -|c| QuagGod|hype -|c| AxeBane|0%. xD -|c| No 1 Machop Fan|lol "0" -|c|★Crime♥|anyone wanna battle me after this game? -|c| AxeBane|GG. -|c| The ✔️erlisify|CHEF BOY4RDEEZNUTS for SPL -|c| The Master Bait|Struggle <3 -|c| lordkaelros|God no -|c| CoolSwag2015|nice 0% -|c| Kyorem|I will crime -|c| CoolSwag2015|Crime go to sleep imo -|c| Rath111|struggle -|c| TheCanadianWifier|LOL Crime -|c| Kyorem|:]] -|c| QuagGod|dw guys -|c| weird random|**zero** -|c| QuagGod|just bring hoopa-u -|c| CoolSwag2015|its been 7 hours hasnt it lol -|c| QuagGod|ez -|c| Aluminion|the struggle is real -|c| Aluminion|lol -|c| memethany fantango|ez for stall -|c|★Crime♥|im crying i lost -|c| weird random|**gg kids** -|c| Asada Shino San|I finished my dinner this is still not done? -|choice|move 4|move 1 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|319/394 tox -|-activate|p2a: Slowbro|move: Struggle -|move|p2a: Slowbro|Struggle|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|214/363 brn -|-damage|p2a: Slowbro|221/394 tox|[from] recoil -| -|-heal|p1a: U Jelly Bruh?|236/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|191/363 brn|[from] brn -|-damage|p2a: Slowbro|125/394 tox|[from] psn -|turn|1067 -|c| Kuronachan|ah yes, that 0 hp damage -|c| Amber Torrey|pretty sure this is the opposite of a good game -|c| lordkaelros|I'll just bring Mmedi and hoopa U -|c| The Master Bait|Forfeit now! -|c| Kuronachan|mega slowbro is a spinblocker -|c| Neith Cass|It's still loading -|c| Honoka Kurai|bay bay ma' boy -|c| Aluminion|2 more turns -|c| CoolSwag2015|1067 -|c| Kudasaii|its gonna be 1069 -|c| Aluminion|actually 1 more -|c| StAlRuth|GGGGG -|c| Kudasaii|1068 -|c| CoolSwag2015|everyone just got trolled -|c| CoolSwag2015|:^) -|c| Cryolite|it ends on 1068 -|c| Rath111|its gonna be 1069 -|c| laxs|One more -|c| AxeBane|Toxic's gonna wipe out Slowbro. -|c| The Master Bait|1068. -|c| Dual Screens Mamo|ITS GONNA END AT 1068 ;-; -|c| QuagGod|o fuck -|c| Cambuur Zygarden|lose by timer -|c| laxs|1068 -|c| memethany fantango|recover -|c| StAlRuth|it ends now -|c| Rath111|nooo -|choice|move 4|move 1 -| -|move|p1a: U Jelly Bruh?|Rapid Spin|p2a: Slowbro -|-damage|p2a: Slowbro|122/394 tox -|-activate|p2a: Slowbro|move: Struggle -|move|p2a: Slowbro|Struggle|p1a: U Jelly Bruh? -|-damage|p1a: U Jelly Bruh?|149/363 brn -|-damage|p2a: Slowbro|24/394 tox|[from] recoil -| -|-heal|p1a: U Jelly Bruh?|171/363 brn|[from] item: Black Sludge -|-damage|p1a: U Jelly Bruh?|126/363 brn|[from] brn -|-damage|p2a: Slowbro|0 fnt|[from] psn -|faint|p2a: Slowbro -| -|win|CHEF BOY4RDEEZNUTS -|c| Rath111|1068 -|c| Enzonana|TENTACRUEL HEAL PULSE -|raw|CHEF BOY4RDEEZNUTS's rating: 1420 → 1436
    (+16 for winning) -|raw|Crime♥'s rating: 1339 → 1323
    (-16 for losing) -|c| Enzonana|GO -|c| Kyorem|1068 is the end -|c| AxeBane|It's not gonna make it to 1069. xD -|c| memethany fantango|for 1069 -|c| Kudasaii|WHERES RECOVER -|c| Cryolite|end battle get -|c| lordkaelros|SO CLOSE -|c| Kyorem|GG -|c| weird random|**it ends at 1068** -|c| icyee|it done -|c| AxeBane|Omai. -|c| weird random|LOL -|c| ZzamanN|**IT'S OVER!** -|c| Asada Shino San|gg -|c| TheCanadianWifier|**GG!** -|c| CoolSwag2015|RIP turn number lol -|c| ZzamanN|**IT'S OVER!** -|c| Kuronachan|I CANT BELIEVE THIS -|c| PyoroLoli|ded at 1068 -|c|★Crime♥|GG WP -|c| AxeBane|GG. -|c|★CHEF BOY4RDEEZNUTS|CRIME GG I'M GLAD I STUCK THIS THROUGH -|c| StAlRuth|GG -|c| StAlRuth|G -|c| StAlRuth|G -|c| ZzamanN|**IT'S OVER!** -|c| breloomiswaifu|gg -|c| 1+8=th|GG -|c| Dual Screens Mamo|GG -|c| Enzonana|1300 ladder -|c| GiraGoomy|GG -|c|★Crime♥|IM SO BAD -|c| Cryolite|g -|c| TheCanadianWifier|G -|c| Cryolite|g -|c| Chasper|+16 -|c| 1+8=th|GGGGG -|c| TheCanadianWifier|G -|c| Cryolite|g -|c| Cryolite|g -|c|★Crime♥|what a game -|c| Enzonana|JAJAJAJAJAJ -|c| Chasper|+16 -|c| Daze-Senpai|gg -|c| megaslowbro1|g -|c| CoolSwag2015|**GG im screenshotting this** -|c| megaslowbro1|g -|c| sancnea|ggggggggggg -|c| Chasper|+16 -|c| Kudasaii|gg -|c| Kudasaii|gg -|c| Honoka Kurai|G FUCKING G. -|c| Gaussfield|EVERYBODY WINS -|c| Kudasaii|gg -|c| Sweanger|http://strawpoll.me/6185409/ -|c| icyee|gg -|c| sancnea|omg -|c| GiraGoomy|+16 POINTS -|c| Kudasaii|everyone type gg -|c| The Master Bait|All that for +16... -|c| Gaussfield|EVERYBODY LOSES -|c| Kudasaii|everyone type gg -|c| ZzamanN|**G MOTHER FUCKING G** -|c| Amber Torrey|god finally what an annoying battle -|c| JacobWorld|gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg -|c| Kudasaii|type gg to win -|c| sancnea|lol -|c| Kudasaii|gg -|c| The Master Bait|Well, whatever, I'm off. -|c| lordkaelros|+16 points -|c| weird random|**everybody won** -|raw|
    Moderated chat was set to +!
    Only users of rank + and higher can talk.
    -|c|★Crime♥|that was a stall battle -|c|★Crime♥|hope i have followers <3 -|c|★Crime♥|lol -|c|★Crime♥|even tho i lost -|c|★Crime♥|T.T -|c|★CHEF BOY4RDEEZNUTS|its was a good game -|c|★Crime♥|thank you all for watching -|c|★Crime♥|yes -|c|★Crime♥|it was my best game ever -|c|★Crime♥|im so exhausted.. -|c|★CHEF BOY4RDEEZNUTS|its 6 am here -|c|★Crime♥|1 in the afternoon here -|c|★Crime♥|i started to play against you around 5 in the morning -|c|★Crime♥|im not sure though -|c|★Crime♥|arounds that -|c|★CHEF BOY4RDEEZNUTS|welp on that note i think im going to bed -|c|@Former Hope|Chef, honor those 16 points with your life. -|c|★Crime♥|lol -|c|★CHEF BOY4RDEEZNUTS|totes worth it -|c|★CHEF BOY4RDEEZNUTS|lol -|c|★CHEF BOY4RDEEZNUTS|night -|c|★Crime♥|night -|c|★Crime♥|:D -|player|p1 diff --git a/old-replays/js/smogtours-ou-509.log b/old-replays/js/smogtours-ou-509.log deleted file mode 100644 index ffecb69c56..0000000000 --- a/old-replays/js/smogtours-ou-509.log +++ /dev/null @@ -1,5064 +0,0 @@ -|join|Lord Elyis -|join|Lady bug -|player|p1|Lord Elyis|1 -|player|p2|Lady bug|66 -|gametype|singles -|gen|6 -|tier|OU -|clearpoke -|poke|p1|Chansey, F -|poke|p1|Gliscor, M -|poke|p1|Skarmory, F -|poke|p1|Venusaur, M -|poke|p1|Quagsire, M -|poke|p1|Heatran, M -|poke|p2|Abomasnow, M -|poke|p2|Skarmory, M -|poke|p2|Nidoqueen, F -|poke|p2|Blissey, F -|poke|p2|Clefable, M -|poke|p2|Gyarados, F -|rule|Sleep Clause Mod: Limit one foe put to sleep -|rule|Species Clause: Limit one of each Pokemon -|rule|OHKO Clause: OHKO moves are banned -|rule|Moody Clause: Moody is banned -|rule|Evasion Moves Clause: Evasion moves are banned -|rule|Endless Battle Clause: Forcing endless battles is banned. -|rule|HP Percentage Mod: HP is reported as percentages -|teampreview -|chat|Colchonero|hail pls -|chat|Pwnemon|lady bugs teams -|chat|zdrup|lol boss -|chat|Pwnemon|are always amazing -|chat|Pwnemon|how does he do it -| -|start -|switch|p1a: Heatran|Heatran, M|385/385 -|switch|p2a: Nidoqueen|Nidoqueen, F|384/384 -|turn|1 -|chat|macle|goooooooo lb -| -|switch|p1a: Chansey|Chansey, F|660/660 -|switch|p2a: Blissey|Blissey, F|688/688 -| -|turn|2 -|chat|Pwnemon|lol -|chat|Valentine|:] -|chat|Arcticblast|Mirror mirror on the wall, who is the fattest of them all? -|chat|Hugendugen|mmm this is arousing -| -|switch|p2a: Nidoqueen|Nidoqueen, F|384/384 -|move|p1a: Chansey|Toxic|p2a: Nidoqueen -|-fail|p2a: Nidoqueen -| -|turn|3 -| -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|284/384 -| -|-heal|p2a: Nidoqueen|308/384|[from] item: Leftovers -|turn|4 -|chat|M Dragon|LOL -|chat|M Dragon|the DP team! -| -|switch|p2a: Skarmory|Skarmory, M|334/334 -|move|p1a: Chansey|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|234/334 -|-damage|p1a: Chansey|550/660|[from] item: Rocky Helmet|[of] p2a: Skarmory -| -|turn|5 -|chat|Pwnemon|but he has a venusaur -|chat|Blue Eon|v. xy -|chat|Pwnemon|?_? -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|move|p2a: Skarmory|Whirlwind|p1a: Skarmory -|drag|p1a: Gliscor|Gliscor, M|353/353 -| -|-activate|p1a: Gliscor|item: Toxic Orb -|-status|p1a: Gliscor|tox -|turn|6 -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Skarmory -|-unboost|p1a: Skarmory|atk|1 -| -|turn|7 -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Skarmory|Skarmory, M|234/334 -| -|turn|8 -| -|switch|p2a: Nidoqueen|Nidoqueen, F|308/384 -|move|p1a: Skarmory|Defog|p2a: Nidoqueen -|-unboost|p2a: Nidoqueen|evasion|1 -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -| -|-heal|p2a: Nidoqueen|332/384|[from] item: Leftovers -|turn|9 -| -|switch|p1a: Venusaur|Venusaur, M|364/364 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Venusaur -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|356/384|[from] item: Leftovers -|turn|10 -|chat|Pwnemon|lb gives no fucks -|chat|Pwnemon|tspikes down? set more tspikes -|chat|THE_IRON_KENYAN|is thizs the hype match u were talkinga but -|chat|M Dragon|darkrai -|chat|THE_IRON_KENYAN|pwenemon -| -|switch|p2a: Skarmory|Skarmory, M|234/334 -|-formechange|p1a: Venusaur|Venusaur-Mega -|message|Venusaur has Mega Evolved into Mega Venusaur! -|move|p1a: Venusaur|Giga Drain|p2a: Skarmory -|-resisted|p2a: Skarmory -|-damage|p2a: Skarmory|204/334 -| -|turn|11 -|chat|THE_IRON_KENYAN|man i suck at typing today -|chat|Valentine|delicious stall v stall -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|334/334 -| -|turn|12 -|chat|Pwnemon|yea tik -| -|switch|p2a: Nidoqueen|Nidoqueen, F|356/384 -|move|p1a: Skarmory|Defog|p2a: Nidoqueen -|-unboost|p2a: Nidoqueen|evasion|1 -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -| -|-heal|p2a: Nidoqueen|380/384|[from] item: Leftovers -|turn|13 -|chat|THE_IRON_KENYAN|is this uu -|chat|THE_IRON_KENYAN|nah ou -|chat|THE_IRON_KENYAN|hey its lady bug the king frog -| -|switch|p1a: Chansey|Chansey, F|550/660 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|384/384|[from] item: Leftovers -|turn|14 -|chat|Pwnemon|u always ask if its uu when ladybug plays -|chat|Pwnemon|tbh -| -|switch|p2a: Skarmory|Skarmory, M|334/334 -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 -| -|turn|15 -|chat|Pwnemon|hard to tell -|chat|THE_IRON_KENYAN|wow -| -|switch|p2a: Abomasnow|Abomasnow, M|384/384 -|-weather|Hail -|switch|p1a: Skarmory|Skarmory, F|334/334 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|314/334|[from] Hail -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|16 -|chat|THE_IRON_KENYAN|how did joim win -|chat|THE_IRON_KENYAN|a battle -|chat|THE_IRON_KENYAN|amazing -|chat|THE_IRON_KENYAN|mvpmvp -| -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|message|Abomasnow has Mega Evolved into Mega Abomasnow! -|move|p1a: Skarmory|Roost|p1a: Skarmory -|-fail|p1a: Skarmory -|move|p2a: Abomasnow|Blizzard|p1a: Skarmory -|-damage|p1a: Skarmory|67/334 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|47/334|[from] Hail -|-heal|p1a: Skarmory|67/334|[from] item: Leftovers -|turn|17 -|chat|Colchonero|oh -| -|move|p1a: Skarmory|Roost|p1a: Skarmory -|-heal|p1a: Skarmory|234/334 -|move|p2a: Abomasnow|Leech Seed|p1a: Skarmory -|-start|p1a: Skarmory|move: Leech Seed -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|214/334|[from] Hail -|-heal|p1a: Skarmory|234/334|[from] item: Leftovers -|-damage|p1a: Skarmory|193/334|[from] Leech Seed|[of] p2a: Abomasnow -|turn|18 -|chat|Blue Eon|THE CHOKE -|chat|Laga|big plays? -|chat|macle|how dare u insult joim -|chat|blarajan|didn't you read -|chat|blarajan|youngjake's explanation? -| -|switch|p1a: Heatran|Heatran, M|385/385 -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|370/394|[from] Hail -|-damage|p1a: Heatran|361/385|[from] Hail -|-heal|p2a: Gyarados|394/394|[from] item: Leftovers -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|turn|19 -|chat|blarajan|he gave four good reasons as to why he lost -|chat|blarajan|none of them involving "joim playing well" -|chat|Philip7086|goddamn, strong af -| -|switch|p1a: Skarmory|Skarmory, F|193/334 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-weather|none -|-heal|p1a: Skarmory|213/334|[from] item: Leftovers -|turn|20 -|chat|Philip7086|lady thug da bez -|chat|Pwnemon|lol -| -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-crit|p1a: Skarmory -|-damage|p1a: Skarmory|69/334 -|move|p1a: Skarmory|Roost|p1a: Skarmory -|-heal|p1a: Skarmory|236/334 -| -|-heal|p1a: Skarmory|256/334|[from] item: Leftovers -|turn|21 -| -|switch|p2a: Abomasnow|Abomasnow, M|384/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-weather|Hail -|move|p1a: Skarmory|Roost|p1a: Skarmory -|-heal|p1a: Skarmory|334/334 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|314/334|[from] Hail -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|22 -|chat|Pwnemon|blara my fave was -|chat|Pwnemon|'surprisingly smart plays' -| -|switch|p1a: Heatran|Heatran, M|385/385 -|switch|p2a: Skarmory|Skarmory, M|334/334 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Heatran|361/385|[from] Hail -|-damage|p2a: Skarmory|314/334|[from] Hail -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|turn|23 -|chat|blarajan|lol -|chat|Pwnemon|like 'i expected joim to be retarded' -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Skarmory -|-unboost|p1a: Skarmory|atk|1 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|370/394|[from] Hail -|-damage|p1a: Skarmory|314/334|[from] Hail -|-heal|p2a: Gyarados|394/394|[from] item: Leftovers -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|24 -|chat|macle|oh shit -|chat|Soulgazer|pwnemon why are you always mad @ yung -|chat|Soulgazer|:'( -| -|switch|p2a: Skarmory|Skarmory, M|314/334 -|move|p1a: Skarmory|Defog|p2a: Skarmory -|-unboost|p2a: Skarmory|evasion|1 -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -| -|-weather|Hail|[upkeep] -|-damage|p2a: Skarmory|294/334|[from] Hail -|-damage|p1a: Skarmory|314/334|[from] Hail -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|25 -|chat|Laga|it's because he secretcly envy he yuth -| -|switch|p2a: Nidoqueen|Nidoqueen, F|384/384 -|switch|p1a: Heatran|Heatran, M|385/385 -| -|-weather|none -|turn|26 -|chat|Soulgazer|so yung.. -|chat|Pwnemon|wish i could b yung again -|chat|Laga|2 yung 4 pwne to bear -| -|switch|p1a: Chansey|Chansey, F|660/660 -|move|p2a: Nidoqueen|Earth Power|p1a: Chansey -|-damage|p1a: Chansey|602/660 -| -|turn|27 -|chat|Arcticblast|Pwnemon you're like 16 -|chat|Pwnemon|shut up -| -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|284/384 -| -|-heal|p2a: Nidoqueen|308/384|[from] item: Leftovers -|turn|28 -| -|switch|p1a: Venusaur|Venusaur, M|364/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -|move|p2a: Nidoqueen|Flamethrower|p1a: Venusaur -|-supereffective|p1a: Venusaur -|-damage|p1a: Venusaur|316/364 -| -|-heal|p2a: Nidoqueen|332/384|[from] item: Leftovers -|turn|29 -|chat|dekzeh|bs no burn -|chat|macle|the damage -|chat|OU Mew|stronk -|chat|chieliee|no burn bs -| -|switch|p2a: Skarmory|Skarmory, M|294/334 -|switch|p1a: Chansey|Chansey, F|602/660 -| -|turn|30 -|chat|Pwnemon|lol that fuckin bulk -|chat|Pwnemon|my god -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|move|p2a: Skarmory|Brave Bird|p1a: Skarmory -|-crit|p1a: Skarmory -|-resisted|p1a: Skarmory -|-damage|p1a: Skarmory|282/334 -|-damage|p2a: Skarmory|277/334|[from] recoil|[of] p1a: Skarmory -| -|-heal|p1a: Skarmory|302/334|[from] item: Leftovers -|turn|31 -|chat|macle|THE DAMAGE -|chat|Pwnemon|bs crit no gg -|chat|Hot N Cold|500 turns battle -| -|switch|p2a: Nidoqueen|Nidoqueen, F|332/384 -|move|p1a: Skarmory|Whirlwind|p2a: Nidoqueen -|drag|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Skarmory -|-unboost|p1a: Skarmory|atk|1 -| -|-heal|p1a: Skarmory|322/334|[from] item: Leftovers -|turn|32 -|chat|Hot N Cold|please -|chat|chieliee|yeah this could take a long while -|chat|Laga|so is anything going to happen or -|chat|Pwnemon|pp stall battle -| -|switch|p2a: Abomasnow|Abomasnow, M|384/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-weather|Hail -|switch|p1a: Quagsire|Quagsire, M|393/393 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Quagsire|369/393|[from] Hail -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|33 -|chat|Pwnemon|its like playing gsc -|chat|Pwnemon|lelele -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Abomasnow|Leech Seed|p1a: Heatran|[miss] -|-miss|p2a: Abomasnow|p1a: Heatran -| -|-weather|Hail|[upkeep] -|-damage|p1a: Heatran|361/385|[from] Hail -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|turn|34 -|chat|Pwnemon|wow -|chat|Arcticblast|hax -|chat|Laga|show us the EQ -|chat|chieliee|where's the earthquake -|chat|Pwnemon|that just extended this match -|chat|Pwnemon|by 200 turns -|chat|OU Mew|imagine this battle with 5 minutes thinking each turn -| -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Stealth Rock|p2a: Gyarados -|-sidestart|p2: Lady bug|move: Stealth Rock -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|370/394|[from] Hail -|-damage|p1a: Heatran|361/385|[from] Hail -|-heal|p2a: Gyarados|394/394|[from] item: Leftovers -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|turn|35 -|chat|SoulWind|you niggers should both tie -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|move|p2a: Gyarados|Earthquake|p1a: Quagsire -|-damage|p1a: Quagsire|323/393 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|370/394|[from] Hail -|-damage|p1a: Quagsire|299/393|[from] Hail -|-heal|p2a: Gyarados|394/394|[from] item: Leftovers -|-heal|p1a: Quagsire|323/393|[from] item: Leftovers -|turn|36 -|chat|Pwnemon|oh shit the rocks -| -|switch|p2a: Blissey|Blissey, F|688/688 -|-damage|p2a: Blissey|602/688|[from] Stealth Rock -|move|p1a: Quagsire|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -| -|-weather|none -|-heal|p2a: Blissey|645/688 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|347/393|[from] item: Leftovers -|-damage|p2a: Blissey|602/688 tox|[from] psn -|turn|37 -|chat|gr8astard|lady bug's stall got buffed :[l] -| -|switch|p2a: Skarmory|Skarmory, M|277/334 -|-damage|p2a: Skarmory|236/334|[from] Stealth Rock -|switch|p1a: Chansey|Chansey, F|602/660 -| -|turn|38 -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Skarmory|Defog|p1a: Heatran -|-unboost|p1a: Heatran|evasion|1 -|-sideend|p2: Lady bug|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|39 -| -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Stealth Rock|p2a: Gyarados -|-sidestart|p2: Lady bug|move: Stealth Rock -| -|turn|40 -| -|switch|p1a: Skarmory|Skarmory, F|322/334 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|41 -| -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-damage|p1a: Skarmory|234/334 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Abomasnow|Abomasnow, M|384/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-damage|p2a: Abomasnow|288/384|[from] Stealth Rock -|-weather|Hail -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|214/334|[from] Hail -|-heal|p1a: Skarmory|234/334|[from] item: Leftovers -|turn|42 -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Abomasnow|Blizzard|p1a: Heatran -|-resisted|p1a: Heatran -|-damage|p1a: Heatran|345/385 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Heatran|321/385|[from] Hail -|-heal|p1a: Heatran|345/385|[from] item: Leftovers -|turn|43 -| -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-damage|p2a: Gyarados|296/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Lava Plume|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|237/394 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|213/394|[from] Hail -|-damage|p1a: Heatran|321/385|[from] Hail -|-heal|p2a: Gyarados|237/394|[from] item: Leftovers -|-heal|p1a: Heatran|345/385|[from] item: Leftovers -|turn|44 -| -|switch|p1a: Quagsire|Quagsire, M|347/393 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|213/394|[from] Hail -|-damage|p1a: Quagsire|323/393|[from] Hail -|-heal|p2a: Gyarados|237/394|[from] item: Leftovers -|-heal|p1a: Quagsire|347/393|[from] item: Leftovers -|turn|45 -|chat|Valentine|Blizzard / Leech Seed ? -|chat|Pwnemon|bs no burn no gg -|chat|Valentine|Whats teh rest of his set, have we seen it -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|254/393 -|move|p1a: Quagsire|Toxic|p2a: Gyarados -|-status|p2a: Gyarados|tox -| -|-weather|none -|-heal|p2a: Gyarados|261/394 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|278/393|[from] item: Leftovers -|-damage|p2a: Gyarados|237/394 tox|[from] psn -|turn|46 -|chat|chieliee|im guessing protect -|chat|Valentine|jw -|chat|chieliee|oh wait we're not supposed to talk -|chat|chieliee|about this -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Recover|p1a: Quagsire -|-heal|p1a: Quagsire|393/393 -| -|turn|47 -|chat|chieliee|oups -|chat|Pwnemon|LOL -|chat|Arcticblast|LB hasn't revealed anything else -|chat|Pwnemon|rekt -|chat|Valentine|i was asking what has been releaved -|chat|zdrup|yeah, I'm banning you chieliee -|chat|Valentine|kk -|chat|Valentine|ty -|chat|Hot N Cold|ban chieliee imo :P -| -|switch|p1a: Skarmory|Skarmory, F|234/334 -|cant|p2a: Gyarados|slp -| -|-heal|p1a: Skarmory|254/334|[from] item: Leftovers -|turn|48 -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Blissey|Blissey, F|602/688 -|-damage|p2a: Blissey|516/688|[from] Stealth Rock -| -|-heal|p1a: Skarmory|274/334|[from] item: Leftovers -|-heal|p2a: Blissey|559/688|[from] item: Leftovers -|turn|49 -| -|switch|p1a: Chansey|Chansey, F|602/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|502/660 -| -|-heal|p2a: Blissey|602/688|[from] item: Leftovers -|turn|50 -|chat|Pwnemon|reveal the two sr setters -| -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|402/660 -|move|p1a: Chansey|Seismic Toss|p2a: Blissey -|-damage|p2a: Blissey|502/688 -| -|-heal|p2a: Blissey|545/688|[from] item: Leftovers -|turn|51 -| -|switch|p2a: Skarmory|Skarmory, M|236/334 -|-damage|p2a: Skarmory|195/334|[from] Stealth Rock -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 -| -|turn|52 -| -|switch|p1a: Heatran|Heatran, M|345/385 -|move|p2a: Skarmory|Defog|p1a: Heatran -|-unboost|p1a: Heatran|evasion|1 -|-sideend|p2: Lady bug|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|-heal|p1a: Heatran|369/385|[from] item: Leftovers -|turn|53 -|chat|Laga|if only s-toss could crit -| -|switch|p2a: Nidoqueen|Nidoqueen, F|332/384 -|move|p1a: Heatran|Stealth Rock|p2a: Nidoqueen -|-sidestart|p2: Lady bug|move: Stealth Rock -| -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|-heal|p2a: Nidoqueen|356/384|[from] item: Leftovers -|turn|54 -| -|switch|p1a: Chansey|Chansey, F|660/660 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|380/384|[from] item: Leftovers -|turn|55 -|chat|Arcticblast|crit Seismic Toss is the new best strategy -| -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|280/384 -| -|-heal|p2a: Nidoqueen|304/384|[from] item: Leftovers -|turn|56 -|chat|Pwnemon|dragon tail y/y -| -|switch|p1a: Venusaur|Venusaur, M|316/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Venusaur -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|328/384|[from] item: Leftovers -|turn|57 -|chat|Pwnemon|aw -|chat|Laga|lol -|chat|Imanalt|plays -|chat|chieliee|plays -| -|switch|p2a: Blissey|Blissey, F|545/688 -|-damage|p2a: Blissey|459/688|[from] Stealth Rock -|switch|p1a: Chansey|Chansey, F|660/660 -|-status|p1a: Chansey|psn -| -|-heal|p2a: Blissey|502/688|[from] item: Leftovers -|-damage|p1a: Chansey|578/660 psn|[from] psn -|turn|58 -|chat|davidness|lol -|chat|davidness|stalll shit -| -|switch|p1a: Venusaur|Venusaur, M|316/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -|move|p2a: Blissey|Seismic Toss|p1a: Venusaur -|-damage|p1a: Venusaur|216/364 -| -|-heal|p2a: Blissey|545/688|[from] item: Leftovers -|turn|59 -| -|move|p1a: Venusaur|Synthesis|p1a: Venusaur -|-heal|p1a: Venusaur|364/364 -|move|p2a: Blissey|Seismic Toss|p1a: Venusaur -|-damage|p1a: Venusaur|264/364 -| -|-heal|p2a: Blissey|588/688|[from] item: Leftovers -|turn|60 -|chat|OU Mew|amazing damage against megavenu -| -|switch|p1a: Chansey|Chansey, F|578/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|478/660 -| -|-heal|p2a: Blissey|631/688|[from] item: Leftovers -|turn|61 -|chat|Imanalt|i feel like defog makes stall vs stall so much worse than it used to be... -| -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 tox -| -|-heal|p2a: Blissey|674/688|[from] item: Leftovers -|-damage|p1a: Chansey|619/660 tox|[from] psn -|turn|62 -| -|switch|p2a: Nidoqueen|Nidoqueen, F|328/384 -|-damage|p2a: Nidoqueen|304/384|[from] Stealth Rock -|move|p1a: Chansey|Toxic|p2a: Nidoqueen -|-fail|p2a: Nidoqueen -| -|-heal|p2a: Nidoqueen|328/384|[from] item: Leftovers -|-damage|p1a: Chansey|537/660 tox|[from] psn -|turn|63 -|chat|Arcticblast|we're 63 turns in and it hasn't even been 10 minutes -| -|switch|p1a: Venusaur|Venusaur, M|264/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Venusaur -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|352/384|[from] item: Leftovers -|turn|64 -|chat|Pwnemon|lol -|chat|Pwnemon|blara match is like -| -|switch|p2a: Blissey|Blissey, F|674/688 -|-damage|p2a: Blissey|588/688|[from] Stealth Rock -|move|p1a: Venusaur|Synthesis|p1a: Venusaur -|-heal|p1a: Venusaur|364/364 -| -|-heal|p2a: Blissey|631/688|[from] item: Leftovers -|turn|65 -|chat|Pwnemon|on turn 3 -|chat|Pwnemon|at this point -|chat|blarajan|wasn't my fault :)) -| -|switch|p1a: Chansey|Chansey, F|537/660 -|-status|p1a: Chansey|psn -|switch|p2a: Skarmory|Skarmory, M|195/334 -|-damage|p2a: Skarmory|154/334|[from] Stealth Rock -| -|-damage|p1a: Chansey|455/660 psn|[from] psn -|turn|66 -|chat|Soulgazer|cased vs jayde was worse.. -| -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|321/334 -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 psn -| -|-damage|p1a: Chansey|578/660 psn|[from] psn -|turn|67 -| -|switch|p1a: Venusaur|Venusaur, M|364/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -|move|p2a: Skarmory|Brave Bird|p1a: Venusaur -|-supereffective|p1a: Venusaur -|-damage|p1a: Venusaur|160/364 -|-damage|p2a: Skarmory|254/334|[from] recoil|[of] p1a: Venusaur -| -|turn|68 -|chat|Pwnemon|the whirlwind to quags is real here -|chat|Hot N Cold|lady bug at least has a win condition -|chat|Arcticblast|THE PLAYS -|chat|Laga|oooooh -|chat|dekzeh|plays -|chat|chieliee|plays -|chat|Colchonero|oops -| -|switch|p1a: Skarmory|Skarmory, F|274/334 -|move|p2a: Skarmory|Defog|p1a: Skarmory -|-unboost|p1a: Skarmory|evasion|1 -|-sideend|p2: Lady bug|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|-heal|p1a: Skarmory|294/334|[from] item: Leftovers -|turn|69 -|chat|Pwnemon|such plays -| -|switch|p2a: Nidoqueen|Nidoqueen, F|352/384 -|move|p1a: Skarmory|Whirlwind|p2a: Nidoqueen -|drag|p2a: Clefable|Clefable, M|394/394 -| -|-heal|p1a: Skarmory|314/334|[from] item: Leftovers -|turn|70 -|chat|Pwnemon|have never been seen -|chat|Pwnemon|by mortals -|chat|dekzeh|the clefable is here -| -|switch|p1a: Chansey|Chansey, F|578/660 -|switch|p2a: Gyarados|Gyarados, F|394/394 slp -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Chansey -|-unboost|p1a: Chansey|atk|1 -| -|turn|71 -|chat|Colchonero|MANfable -|chat|dekzeh|n_n -|chat|Joim|70 turns, no kills -|chat|Joim|gg -| -|switch|p1a: Skarmory|Skarmory, F|314/334 -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|72 -|chat|Imanalt|70 turns not even much damage or progress setting hazards -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Blissey|Blissey, F|631/688 -| -|-heal|p2a: Blissey|674/688|[from] item: Leftovers -|turn|73 -|chat|Pwnemon|but pp stall -|chat|Imanalt|fucking defog -|chat|macle|the damage -|chat|Pwnemon|venus half out of synhs -| -|switch|p1a: Gliscor|Gliscor, M|353/353 tox -|switch|p2a: Nidoqueen|Nidoqueen, F|352/384 -| -|-heal|p2a: Nidoqueen|376/384|[from] item: Leftovers -|turn|74 -| -|switch|p1a: Venusaur|Venusaur, M|160/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Venusaur -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|384/384|[from] item: Leftovers -|turn|75 -|chat|Imanalt|yeah its really sad though when thats the most important thing -|chat|Pwnemon|lol -| -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Venusaur -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -|move|p1a: Venusaur|Synthesis|p1a: Venusaur -|-heal|p1a: Venusaur|342/364 -| -|turn|76 -|chat|Joim|wow the plays -| -|switch|p2a: Skarmory|Skarmory, M|254/334 -|switch|p1a: Chansey|Chansey, F|578/660 -|-status|p1a: Chansey|tox -| -|-damage|p1a: Chansey|537/660 tox|[from] psn -|turn|77 -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|move|p2a: Skarmory|Whirlwind|p1a: Skarmory -|drag|p1a: Heatran|Heatran, M|385/385 -| -|turn|78 -|chat|blarajan|joim you're embarrassing yourself :(( -|chat|Pwnemon|aw -|chat|LonelyNess|awwwww -|chat|myzozoa|lol -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Skarmory -|-unboost|p1a: Skarmory|atk|1 -| -|turn|79 -|chat|Imanalt|bb if real -|chat|Arcticblast|I think I'll pass on using stall in OST after this -|chat|Pwnemon|buzz kill -|chat|Imanalt|dam -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Skarmory|Defog|p2a: Gyarados -|-unboost|p2a: Gyarados|evasion|1 -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -| -|turn|80 -|chat|Pwnemon|lol ablast -|chat|Joim|I will copy this stall team -| -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-damage|p1a: Skarmory|243/334 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Clefable|Clefable, M|394/394 -| -|-heal|p1a: Skarmory|263/334|[from] item: Leftovers -|turn|81 -|chat|macle|its ok blara always embarrasses himself -|chat|Annoyer|which one -|chat|Imanalt|lol -|chat|Joim|both -|chat|Pwnemon|one for game 1 -|chat|Pwnemon|one for game 2 -| -|switch|p1a: Chansey|Chansey, F|537/660 -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Chansey -|-unboost|p1a: Chansey|atk|1 -| -|turn|82 -|chat|Pwnemon|if the opponent lives to game 2 -|chat|Pwnemon|without an heroing -| -|switch|p2a: Nidoqueen|Nidoqueen, F|384/384 -|switch|p1a: Skarmory|Skarmory, F|263/334 -| -|-heal|p1a: Skarmory|283/334|[from] item: Leftovers -|turn|83 -|chat|Joim|if there's third match then a full choice team ofc -| -|switch|p1a: Chansey|Chansey, F|537/660 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|turn|84 -| -|switch|p2a: Blissey|Blissey, F|674/688 -|move|p1a: Chansey|Seismic Toss|p2a: Blissey -|-damage|p2a: Blissey|574/688 -| -|-heal|p2a: Blissey|617/688|[from] item: Leftovers -|turn|85 -|chat|OU Mew|suicide by stall -| -|switch|p1a: Skarmory|Skarmory, F|283/334 -|move|p2a: Blissey|Seismic Toss|p1a: Skarmory -|-damage|p1a: Skarmory|183/334 -| -|-heal|p1a: Skarmory|203/334|[from] item: Leftovers -|-heal|p2a: Blissey|660/688|[from] item: Leftovers -|turn|86 -| -|move|p1a: Skarmory|Roost|p1a: Skarmory -|-heal|p1a: Skarmory|334/334 -|move|p2a: Blissey|Seismic Toss|p1a: Skarmory -|-damage|p1a: Skarmory|234/334 -| -|-heal|p1a: Skarmory|254/334|[from] item: Leftovers -|-heal|p2a: Blissey|688/688|[from] item: Leftovers -|turn|87 -|chat|chieliee|both players should just be constantly switching to not use pp -|chat|chieliee|imo -|chat|Pwnemon|yeah -| -|switch|p2a: Abomasnow|Abomasnow, M|288/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-weather|Hail -|move|p1a: Skarmory|Defog|p2a: Abomasnow -|-unboost|p2a: Abomasnow|evasion|1 -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|234/334|[from] Hail -|-heal|p1a: Skarmory|254/334|[from] item: Leftovers -|turn|88 -|chat|macle|winner will be decided by time out to shitting y/n -|chat|Pwnemon|it is prob gonna come to -|chat|Pwnemon|siesmic pp vs synth pp -|chat|Pwnemon|lol -|chat|whistle|this is fucked up -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Abomasnow|Leech Seed|p1a: Heatran -|-start|p1a: Heatran|move: Leech Seed -| -|-weather|Hail|[upkeep] -|-damage|p1a: Heatran|361/385|[from] Hail -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|-damage|p1a: Heatran|337/385|[from] Leech Seed|[of] p2a: Abomasnow -|-heal|p2a: Abomasnow|336/384|[silent] -|turn|89 -|chat|jumpluff|what the fuck -|chat|dekzeh|ure fucked up whistle -|chat|jumpluff|i join turn 88 and it's 6-0 -|chat|dekzeh|o_o -|chat|jdarden|lol -|chat|Pwnemon|lol -|chat|chieliee|stall vs stall -|chat|whistle|im going to go kill myself -|chat|Annoyer|6-6 -|chat|THE_IRON_KENYAN|how is anyone gonna win this game -|chat|jumpluff|would you look at that abomasnow tho. -|chat|THE_IRON_KENYAN|lol -| -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Stealth Rock|p2a: Gyarados -|-sidestart|p2: Lady bug|move: Stealth Rock -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|370/394|[from] Hail -|-damage|p1a: Heatran|313/385|[from] Hail -|-heal|p2a: Gyarados|394/394|[from] item: Leftovers -|-heal|p1a: Heatran|337/385|[from] item: Leftovers -|-damage|p1a: Heatran|289/385|[from] Leech Seed|[of] p2a: Gyarados -|turn|90 -|chat|Laga|TIK -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|370/394|[from] Hail -|-damage|p1a: Quagsire|369/393|[from] Hail -|-heal|p2a: Gyarados|394/394|[from] item: Leftovers -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|91 -|chat|Laga|I am having a struggle seeing how -|chat|Pwnemon|laga that was forced -| -|switch|p2a: Blissey|Blissey, F|688/688 -|-damage|p2a: Blissey|602/688|[from] Stealth Rock -|move|p1a: Quagsire|Scald|p2a: Blissey -|-damage|p2a: Blissey|553/688 -| -|-weather|none -|-heal|p2a: Blissey|596/688|[from] item: Leftovers -|turn|92 -|chat|Laga|shut up. -| -|switch|p1a: Gliscor|Gliscor, M|353/353 tox -|move|p2a: Blissey|Seismic Toss|p1a: Gliscor -|-damage|p1a: Gliscor|253/353 tox -| -|-heal|p2a: Blissey|639/688|[from] item: Leftovers -|-heal|p1a: Gliscor|297/353 tox|[from] ability: Poison Heal -|turn|93 -| -|switch|p1a: Heatran|Heatran, M|289/385 -|switch|p2a: Skarmory|Skarmory, M|254/334 -|-damage|p2a: Skarmory|213/334|[from] Stealth Rock -| -|-heal|p1a: Heatran|313/385|[from] item: Leftovers -|turn|94 -|chat|Pwnemon|plays -|chat|Treecko|cripple fiiiight -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-damage|p2a: Gyarados|296/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Quagsire -|-unboost|p1a: Quagsire|atk|1 -| -|-heal|p2a: Gyarados|320/394|[from] item: Leftovers -|turn|95 -|chat|THE_IRON_KENYAN|leche seed -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|287/394 -|-status|p2a: Gyarados|brn -| -|-heal|p2a: Gyarados|311/394 brn|[from] item: Leftovers -|-damage|p2a: Gyarados|262/394 brn|[from] brn -|turn|96 -|chat|Soulgazer|nb -|chat|Joim|wow -|chat|macle|NOooooooo -|chat|Biosci|yessssss -|chat|LonelyNess|he has rest -|chat|chieliee|it has rest -|chat|Pwnemon|its ok rest lelele -|chat|Joim|fuck man -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-crit|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|208/394 brn -| -|-heal|p2a: Gyarados|232/394 brn|[from] item: Leftovers -|-damage|p2a: Gyarados|183/394 brn|[from] brn -|turn|97 -|chat|Biosci|progress -|chat|THE_IRON_KENYAN|is this an spl match -|chat|LonelyNess|calm your tits lol -|chat|THE_IRON_KENYAN|? -|chat|Pwnemon|y -|chat|Soulgazer|it has rest so 'lol' -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|358/394 slp -| -|-heal|p2a: Gyarados|382/394 slp|[from] item: Leftovers -|turn|98 -|chat|THE_IRON_KENYAN|PH SHIT -|chat|OU Mew|HP Electric -|chat|THE_IRON_KENYAN|SHEIIT -|chat|THE_IRON_KENYAN|SHEEIT -|chat|Hot N Cold|soulhaxer -|chat|Joim|I went here later on -|chat|Joim|don't hate -|chat|Hot N Cold| :{|} -| -|switch|p1a: Skarmory|Skarmory, F|254/334 -|cant|p2a: Gyarados|slp -| -|-heal|p2a: Gyarados|394/394 slp|[from] item: Leftovers -|-heal|p1a: Skarmory|274/334|[from] item: Leftovers -|turn|99 -|chat|THE_IRON_KENYAN|its got rest -|chat|Pwnemon|lets predict final turn # -|chat|Soulgazer|i can see why tho -|chat|THE_IRON_KENYAN|i know it in my heart -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Blissey|Blissey, F|639/688 -|-damage|p2a: Blissey|553/688|[from] Stealth Rock -| -|-heal|p1a: Skarmory|294/334|[from] item: Leftovers -|-heal|p2a: Blissey|596/688|[from] item: Leftovers -|turn|100 -|chat|Pwnemon|i bet 100 -|chat|chieliee|has gyara revealed it's last move yet -|chat|Pwnemon|er -|chat|Pwnemon|1000 -|chat|Pwnemon|lol -|chat|Soulgazer|chielee -| -|switch|p1a: Chansey|Chansey, F|537/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|437/660 -| -|-heal|p2a: Blissey|639/688|[from] item: Leftovers -|turn|101 -|chat|Treecko|it's resttalk -|chat|Pwnemon|no chie -|chat|Texas Cloverleaf|it has -|chat|Soulgazer|its rest dd wfall eq -|chat|Laga|nice prediction pwne -|chat|Joim|Stall games start breaking after 200 -|chat|Treecko|oh -|chat|Laga|this is where one of em times out -|chat|Treecko|or not -|chat|Arcticblast|yeah chieliee, it has -|chat|Treecko|:) -| -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -|move|p1a: Chansey|Toxic|p2a: Blissey|[miss] -|-miss|p1a: Chansey|p2a: Blissey -| -|-heal|p2a: Blissey|682/688|[from] item: Leftovers -|-damage|p1a: Chansey|396/660 tox|[from] psn -|turn|102 -|chat|chieliee|did he show eq -|chat|Soulgazer|y -|chat|Pwnemon|y -|chat|Soulgazer|lol -| -|switch|p2a: Nidoqueen|Nidoqueen, F|384/384 -|-damage|p2a: Nidoqueen|360/384|[from] Stealth Rock -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 tox -| -|-heal|p2a: Nidoqueen|384/384|[from] item: Leftovers -|-damage|p1a: Chansey|578/660 tox|[from] psn -|turn|103 -|chat|Hot N Cold|which waste PP loses this game lol -|chat|THE_IRON_KENYAN|is this what gsc is like -|chat|jumpluff|it's like gsc -|chat|Pwnemon|i think blisseys seismic toss -|chat|jumpluff|.. -|chat|THE_IRON_KENYAN|lel -|chat|Pwnemon|will decide the game -|chat|Pwnemon|funnily -| -|switch|p1a: Venusaur|Venusaur, M|342/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Venusaur -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|turn|104 -|chat|myzozoa|xy sux y/n -|chat|Pwnemon|all the gsc games this spl -|chat|Pwnemon|have been pretty quick -|chat|jumpluff|sub in myzo -|chat|THE_IRON_KENYAN|i wonder if i have time to brush my teeth before this battle is over -|chat|jumpluff|bring the fire -| -|move|p2a: Nidoqueen|Flamethrower|p1a: Venusaur -|-supereffective|p1a: Venusaur -|-damage|p1a: Venusaur|294/364 -|move|p1a: Venusaur|Earthquake|p2a: Nidoqueen -|-supereffective|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|250/384 -| -|-heal|p2a: Nidoqueen|274/384|[from] item: Leftovers -|turn|105 -|chat|Pwnemon|you have time to cook a four course meal -|chat|Stone_Cold22|lol -|chat|Joim|"it's super effective" -|chat|Pwnemon|before this shit ends -|chat|BAIKA|thick fat ^_____^ -| -|switch|p1a: Chansey|Chansey, F|578/660 -|-status|p1a: Chansey|psn -|move|p2a: Nidoqueen|Flamethrower|p1a: Chansey -|-damage|p1a: Chansey|542/660 psn -| -|-heal|p2a: Nidoqueen|298/384|[from] item: Leftovers -|-damage|p1a: Chansey|460/660 psn|[from] psn -|turn|106 -|chat|Soulgazer|pwnemon, atleast they play quickly -|chat|jumpluff|yeah jesus -|chat|Treecko|yea lol -|chat|Pwnemon|lol tru -|chat|Soulgazer|took 1hour+ for cased and jayde to play -|chat|Soulgazer|20 turns -| -|switch|p2a: Skarmory|Skarmory, M|213/334 -|-damage|p2a: Skarmory|172/334|[from] Stealth Rock -|switch|p1a: Venusaur|Venusaur, M|294/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -| -|turn|107 -|chat|Joim|yeah I know -|chat|Joim|it's just funny -|chat|jumpluff|cased vs. problems was the worst -| -|switch|p1a: Heatran|Heatran, M|313/385 -|move|p2a: Skarmory|Defog|p1a: Heatran -|-unboost|p1a: Heatran|evasion|1 -|-sideend|p2: Lady bug|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|-heal|p1a: Heatran|337/385|[from] item: Leftovers -|turn|108 -|chat|jumpluff|i nearly killed myself staying awake through that cos i was sick -|chat|Annoyer|when did this match start btw -|chat|Pwnemon|they dont play the same tier -|chat|blarajan|cased definitely fought problems -|chat|Pwnemon|lol -|chat|myzozoa|how many defogs do they each ahve -|chat|Treecko|lol -|chat|Soulgazer|annoyer -|chat|Soulgazer|like -| -|switch|p2a: Nidoqueen|Nidoqueen, F|298/384 -|move|p1a: Heatran|Stealth Rock|p2a: Nidoqueen -|-sidestart|p2: Lady bug|move: Stealth Rock -| -|-heal|p1a: Heatran|361/385|[from] item: Leftovers -|-heal|p2a: Nidoqueen|322/384|[from] item: Leftovers -|turn|109 -|chat|Soulgazer|10min ago? -|chat|Soulgazer|idk -|chat|Annoyer|lol damn -|chat|Laga|started just before you got on irc annoyer -|chat|Pwnemon|20 i think -|chat|Arcticblast|15 minutes ago -|chat|chieliee|20 -| -|switch|p1a: Chansey|Chansey, F|460/660 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|346/384|[from] item: Leftovers -|turn|110 -|chat|blarajan|i love how over entitled spectators are o.O -|chat|Pwnemon|uh wow -|chat|Pwnemon|six -|chat|Pwnemon|rofl -| -|switch|p2a: Blissey|Blissey, F|682/688 -|-damage|p2a: Blissey|596/688|[from] Stealth Rock -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 -| -|-heal|p2a: Blissey|639/688|[from] item: Leftovers -|turn|111 -|chat|Pwnemon|six mins ago -|chat|Arcticblast|oh 20 w/e -|chat|Pwnemon|and on turn 110 -|chat|Hugendugen|what turn are we up to? -| -|switch|p1a: Venusaur|Venusaur, M|294/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -|move|p2a: Blissey|Seismic Toss|p1a: Venusaur -|-damage|p1a: Venusaur|194/364 -| -|-heal|p2a: Blissey|682/688|[from] item: Leftovers -|turn|112 -|chat|Annoyer|111 -|chat|Treecko|111 -|chat|jumpluff|that's impressive -|chat|Pwnemon|wait no -|chat|Hugendugen|I just got back and I'm still catching up -|chat|Pwnemon|it got posted twice -|chat|Pwnemon|on irc -| -|switch|p1a: Gliscor|Gliscor, M|297/353 tox -|move|p2a: Blissey|Toxic|p1a: Gliscor -|-fail|p1a: Gliscor|tox -| -|-heal|p2a: Blissey|688/688|[from] item: Leftovers -|-heal|p1a: Gliscor|341/353 tox|[from] ability: Poison Heal -|turn|113 -|chat|Hugendugen|105 atm -|chat|Pwnemon|i foudn the later -|chat|Hugendugen|almost there -|chat|Pwnemon|it was >20 mins -|chat|Treecko|lol -|chat|blarajan|pwnemon -|chat|blarajan|it started 23 minutes ago -| -|switch|p1a: Heatran|Heatran, M|361/385 -|switch|p2a: Gyarados|Gyarados, F|394/394 slp -|-damage|p2a: Gyarados|296/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -| -|-heal|p2a: Gyarados|320/394 slp|[from] item: Leftovers -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|turn|114 -|chat|Pwnemon|y -|chat|jumpluff|even still 5 turns a minute approx. -|chat|Pwnemon|i got it -|chat|jumpluff|is very solid for this spl -|chat|jumpluff|very good in general -|chat|Treecko|yeah it is -|chat|Stone_Cold22|jumpluff -|chat|Stone_Cold22|first penta in ranked about 30 mins ago -|chat|Stone_Cold22|lfgi? -|chat|jumpluff|grats! what champ -| -|switch|p1a: Skarmory|Skarmory, F|294/334 -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p2a: Gyarados|344/394|[from] item: Leftovers -|-heal|p1a: Skarmory|314/334|[from] item: Leftovers -|turn|115 -|chat|Stone_Cold22|fizz -|chat|jumpluff|nice -|chat|Stone_Cold22|the ew boss -|chat|myzozoa|flinchas -| -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-damage|p1a: Skarmory|224/334 -|cant|p1a: Skarmory|flinch -| -|-heal|p2a: Gyarados|368/394|[from] item: Leftovers -|-heal|p1a: Skarmory|244/334|[from] item: Leftovers -|turn|116 -|chat|Arcticblast|triple crit flinch right here -|chat|myzozoa|weak af -|chat|Hot N Cold|lol quagsire -|chat|Pwnemon|yes flinch -|chat|blarajan|FLINCH 1 FOR THE BUG -|chat|Soulgazer|myzo,, -|chat|chieliee|3 more -|chat|jumpluff|thanks myzo -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Skarmory|Skarmory, M|172/334 -|-damage|p2a: Skarmory|131/334|[from] Stealth Rock -| -|-heal|p1a: Skarmory|264/334|[from] item: Leftovers -|turn|117 -|chat|Soulgazer|dont flinch -|chat|Annoyer|dag. -|chat|Pwnemon|lol the dance -|chat|Hugendugen|ok sweet, finally caught up -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|298/334 -| -|turn|118 -|chat|Pwnemon|where is the defog -| -|switch|p2a: Gyarados|Gyarados, F|368/394 -|-damage|p2a: Gyarados|270/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Roar|p2a: Gyarados -|drag|p2a: Blissey|Blissey, F|688/688 -|-damage|p2a: Blissey|602/688|[from] Stealth Rock -| -|-heal|p2a: Blissey|645/688|[from] item: Leftovers -|turn|119 -|chat|the pdc show|you both just had to bring stall -|chat|Soulgazer|ah not bad -|chat|Valentine|oml -|chat|Stone_Cold22|tbh -|chat|chieliee|ah -| -|switch|p1a: Chansey|Chansey, F|660/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|560/660 -| -|-heal|p2a: Blissey|688/688|[from] item: Leftovers -|turn|120 -|chat|Stone_Cold22|elyis should talked to me before hand -|chat|Stone_Cold22|i woulda told him what lady bug would use -|chat|Stone_Cold22|lol -|chat|Arcticblast|man imagine if that was a Taunt Gyara -|chat|Stone_Cold22|smfh -| -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|460/660 -|move|p1a: Chansey|Seismic Toss|p2a: Blissey -|-damage|p2a: Blissey|588/688 -| -|-heal|p2a: Blissey|631/688|[from] item: Leftovers -|turn|121 -|chat|jumpluff|dude lb told everyone he was gonna use hail stall -|chat|jumpluff|he was warned. -| -|switch|p2a: Skarmory|Skarmory, M|298/334 -|-damage|p2a: Skarmory|257/334|[from] Stealth Rock -|move|p1a: Chansey|Toxic|p2a: Skarmory -|-fail|p2a: Skarmory -| -|turn|122 -|chat|Arcticblast|this game would have been over sixty turns ago -|chat|myzozoa|i like how he still uses nidoqueen on his hail stall -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Skarmory|Defog|p1a: Heatran -|-unboost|p1a: Heatran|evasion|1 -|-sideend|p2: Lady bug|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|turn|123 -|chat|myzozoa|nothing changes -|chat|chieliee|cant these guys just restart with new teams pls -|chat|jumpluff|:') -| -|switch|p2a: Nidoqueen|Nidoqueen, F|346/384 -|move|p1a: Heatran|Stealth Rock|p2a: Nidoqueen -|-sidestart|p2: Lady bug|move: Stealth Rock -| -|-heal|p2a: Nidoqueen|370/384|[from] item: Leftovers -|turn|124 -|chat|Dice|the mcmeghan tactics -|chat|Dice|scouting playstyle and then restarting -| -|switch|p1a: Chansey|Chansey, F|460/660 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|384/384|[from] item: Leftovers -|turn|125 -|chat|Pwnemon|lol -| -|switch|p2a: Skarmory|Skarmory, M|257/334 -|-damage|p2a: Skarmory|216/334|[from] Stealth Rock -|move|p1a: Chansey|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|116/334 -|-damage|p1a: Chansey|350/660|[from] item: Rocky Helmet|[of] p2a: Skarmory -| -|turn|126 -|chat|McMeghan|oO -|chat|Stone_Cold22|the plays -| -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|283/334 -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 -| -|turn|127 -| -|switch|p1a: Skarmory|Skarmory, F|264/334 -|move|p2a: Skarmory|Whirlwind|p1a: Skarmory -|drag|p1a: Quagsire|Quagsire, M|393/393 -|-status|p1a: Quagsire|psn -| -|-damage|p1a: Quagsire|344/393 psn|[from] psn -|turn|128 -|chat|Pwnemon|YES -|chat|blarajan|GOT IT -|chat|LonelyNess|boom -|chat|myzozoa|nice -|chat|Pwnemon|THE REAL -|chat|Colchonero|yeah -|chat|Imanalt|boom -| -|switch|p1a: Skarmory|Skarmory, F|264/334 -|move|p2a: Skarmory|Defog|p1a: Skarmory -|-unboost|p1a: Skarmory|evasion|1 -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -|-sideend|p2: Lady bug|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -| -|-heal|p1a: Skarmory|284/334|[from] item: Leftovers -|turn|129 -|chat|blarajan|heal bell on chansey tho -|chat|myzozoa|seriously? -|chat|blarajan|probably? -|chat|Pwnemon|if there is a god -|chat|chieliee|everything has a 'though' in this battle -| -|switch|p2a: Gyarados|Gyarados, F|270/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Skarmory -|-unboost|p1a: Skarmory|atk|1 -|switch|p1a: Chansey|Chansey, F|660/660 -| -|-heal|p2a: Gyarados|294/394|[from] item: Leftovers -|turn|130 -|chat|Treecko|if it is, that's still one less PP of it :O -| -|switch|p1a: Skarmory|Skarmory, F|284/334 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p2a: Gyarados|318/394|[from] item: Leftovers -|-heal|p1a: Skarmory|304/334|[from] item: Leftovers -|turn|131 -| -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-damage|p1a: Skarmory|213/334 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Nidoqueen|Nidoqueen, F|384/384 -| -|-heal|p1a: Skarmory|233/334|[from] item: Leftovers -|turn|132 -|chat|jumpluff|y'all should start putting spite on ur mons imo -|chat|Laga|man you know you are using some srs stall on stall -|chat|Laga|when spectators are talking about -| -|switch|p1a: Chansey|Chansey, F|660/660 -|move|p2a: Nidoqueen|Flamethrower|p1a: Chansey -|-damage|p1a: Chansey|624/660 -| -|turn|133 -|chat|Laga|stalling out heal bell pp -|chat|Treecko|yea lol -|chat|Imanalt|when are the waterfall flicnhes going to start -|chat|jumpluff|ipl stalled ot rapid spin once -|chat|jumpluff|out* -| -|move|p2a: Nidoqueen|Sludge Wave|p1a: Chansey -|-damage|p1a: Chansey|561/660 -|move|p1a: Chansey|Aromatherapy|p1a: Chansey -|-cureteam|p1a: Chansey|[from] move: Aromatherapy -| -|turn|134 -|chat|Annoyer|mushy stall -|chat|edgrr|:] -|chat|Imanalt|wow amazingly strong -|chat|blarajan|there it is -|chat|macle|there is it -|chat|jdarden|damage -|chat|Soulgazer|ah -|chat|Soulgazer|the wave -|chat|jumpluff|which has 64 PP -| -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|284/384 -| -|-heal|p2a: Nidoqueen|308/384|[from] item: Leftovers -|turn|135 -|chat|Pwnemon|no it has 8 -|chat|Pwnemon|fasten ur fucking seatbelts folks -| -|move|p2a: Nidoqueen|Flamethrower|p1a: Chansey -|-damage|p1a: Chansey|526/660 -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|208/384 -| -|-heal|p2a: Nidoqueen|232/384|[from] item: Leftovers -|turn|136 -|chat|jumpluff|rapid spin >.> -|chat|Pwnemon|this is gonna take a while -|chat|Treecko|she was talking about spin -|chat|Pwnemon|oh -|chat|Treecko|not aromatherapy -|chat|Arcticblast|dear god pluff that sounds awful -|chat|Stone_Cold22|pluff -|chat|THE_IRON_KENYAN|ok i got done brushing my teeth did anything happen -|chat|Stone_Cold22|someone on ladder on shoddy ran -|chat|Treecko|nop -| -|switch|p2a: Gyarados|Gyarados, F|318/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Chansey -|-unboost|p1a: Chansey|atk|1 -|switch|p1a: Venusaur|Venusaur, M|194/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -| -|-heal|p2a: Gyarados|342/394|[from] item: Leftovers -|turn|137 -|chat|Annoyer|revealed aroma -|chat|Laga|wow pluff -|chat|Stone_Cold22|cosmic power rest sleep talk rapid spin claydol -|chat|Stone_Cold22|just to pp stall -|chat|blarajan|i'm genuinely worried lady bug will run out of toxic spike pp -|chat|LonelyNess|THE_IRON_KENYAN: exactly 1 aromatherapy pp was stalled -|chat|Treecko|lol -|chat|jumpluff|rofl stone -|chat|Pwnemon|can i get a -|chat|Stone_Cold22|i was like -| -|switch|p1a: Quagsire|Quagsire, M|344/393 -|move|p2a: Gyarados|Earthquake|p1a: Quagsire -|-damage|p1a: Quagsire|263/393 -| -|-heal|p2a: Gyarados|366/394|[from] item: Leftovers -|-heal|p1a: Quagsire|287/393|[from] item: Leftovers -|turn|138 -|chat|Pwnemon|gothitelle -|chat|Stone_Cold22|RELLY DUDE -|chat|Laga|did the dude have like 3 spikers and 2 rock setters -|chat|Laga|or something -|chat|Stone_Cold22|the 09 days -|chat|Imanalt|ive seen bh games revolve around stalling out spin pps -|chat|LonelyNess|that is the net gain of what has happened thus far -|chat|Raichy|Is this GSC? -| -|switch|p2a: Blissey|Blissey, F|631/688 -|move|p1a: Quagsire|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -| -|-heal|p2a: Blissey|674/688 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|311/393|[from] item: Leftovers -|-damage|p2a: Blissey|631/688 tox|[from] psn -|turn|139 -|chat|Imanalt|only to have the second spinner get revealed in turn 300 -|chat|zfs|nah, gsc is more exciting ;o -|chat|Treecko|aha -|chat|Texas Cloverleaf|gsc would be faster than this -| -|switch|p2a: Abomasnow|Abomasnow, M|336/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-weather|Hail -|switch|p1a: Gliscor|Gliscor, M|341/353 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Gliscor|319/353|[from] Hail -|-activate|p1a: Gliscor|item: Toxic Orb -|-status|p1a: Gliscor|tox -|turn|140 -|chat|jumpluff|omg Imanalt lol -|chat|Raichy|:c -|chat|jdarden|at least they COULD pp stall -|chat|Treecko|plaaaaays -|chat|THE_IRON_KENYAN|he has the advantage -| -|move|p1a: Gliscor|Protect|p1a: Gliscor -|-singleturn|p1a: Gliscor|Protect -|move|p2a: Abomasnow|Leech Seed|p1a: Gliscor -|-activate|p1a: Gliscor|Protect -| -|-weather|Hail|[upkeep] -|-damage|p1a: Gliscor|297/353 tox|[from] Hail -|-heal|p1a: Gliscor|341/353 tox|[from] ability: Poison Heal -|turn|141 -|chat|Pwnemon|real -|chat|jdarden|and didn't fall victim to shuckie -|chat|THE_IRON_KENYAN|THE PALYS -|chat|Imanalt|fucking shuckle -|chat|jumpluff|jdarden :) -|chat|Annoyer|frz -|chat|myzozoa|blizzard try to freeze -|chat|Imanalt|fucking greatsage -| -|move|p1a: Gliscor|Substitute|p1a: Gliscor -|-start|p1a: Gliscor|Substitute -|-damage|p1a: Gliscor|253/353 tox -|move|p2a: Abomasnow|Leech Seed|p1a: Gliscor -| -|-weather|Hail|[upkeep] -|-damage|p1a: Gliscor|231/353 tox|[from] Hail -|-heal|p1a: Gliscor|275/353 tox|[from] ability: Poison Heal -|turn|142 -|chat|Pwnemon|damn -|chat|jdarden|jumpluff :) -|chat|THE_IRON_KENYAN|the plays -|chat|Treecko|:OOOOOOOO -|chat|Stone_Cold22|PLAYS -|chat|Annoyer|ono -|chat|Imanalt|fucking destroyed -|chat|Soulgazer|ah not bad -|chat|Stone_Cold22|MADE -|chat|Valentine|fuckin gg -|chat|Pwnemon|toxic is coming -|chat|Nachos|Ah! -|chat|Soulgazer|NOT BAD -| -|switch|p1a: Heatran|Heatran, M|385/385 -|switch|p2a: Skarmory|Skarmory, M|283/334 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Heatran|361/385|[from] Hail -|-damage|p2a: Skarmory|263/334|[from] Hail -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|turn|143 -|chat|Pwnemon|get out -|chat|Soulgazer|LOL -|chat|Pwnemon|oh shit -|chat|Stone_Cold22|DAM -|chat|Treecko|oml -|chat|Stone_Cold22|THE PREDICS -|chat|THE_IRON_KENYAN|fucking destroyed -|chat|Imanalt|PLAYS -|chat|Imanalt|fuck -| -|switch|p2a: Nidoqueen|Nidoqueen, F|232/384 -|move|p1a: Heatran|Stealth Rock|p2a: Nidoqueen -|-sidestart|p2: Lady bug|move: Stealth Rock -| -|-weather|none -|-heal|p2a: Nidoqueen|256/384|[from] item: Leftovers -|turn|144 -|chat|Imanalt|i have to go to class -|chat|Imanalt|this will probably still be going when i get back tho -|chat|Laga|too bad -|chat|Soulgazer|dw -|chat|Imanalt|:/ -|chat|Treecko|lol -|chat|Treecko|it's ok -|chat|Treecko|yea -|chat|Laga|still nothing happened -|chat|Treecko|exactly -|chat|Soulgazer|it will still be going -| -|switch|p1a: Chansey|Chansey, F|526/660 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|280/384|[from] item: Leftovers -|turn|145 -|chat|Soulgazer|when you come back -|chat|blarajan|are you lot genuinely saying nothing has happened -|chat|Imanalt|if this is still going by then, at the rate theyre palying itll probably be turn 400 or something -|chat|macle|ww in quag :( -|chat|THE_IRON_KENYAN|i wonder if i should rap the whole time this is going on -|chat|SoulWind|you shouldn't -THE_IRON_KENYAN was warned by Arcticblast. (no) -|chat|Laga|blarajan nothing has happened besides pp stall -|chat|Imanalt|blarajan pps have been stalled -| -|switch|p2a: Skarmory|Skarmory, M|263/334 -|-damage|p2a: Skarmory|222/334|[from] Stealth Rock -|move|p1a: Chansey|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|122/334 -|-damage|p1a: Chansey|416/660|[from] item: Rocky Helmet|[of] p2a: Skarmory -| -|turn|146 -|chat|blarajan|yeah that's a lot of things happening -|chat|Imanalt|go for bb supercrit -|chat|blarajan|that's what this game is about lol -|chat|Stinson|has anything lost pp yet? -| -|switch|p1a: Skarmory|Skarmory, F|233/334 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|289/334 -| -|-heal|p1a: Skarmory|253/334|[from] item: Leftovers -|turn|147 -|chat|Stinson|and also is this an SPL game>? -|chat|Pwnemon|y -| -|move|p1a: Skarmory|Defog|p2a: Skarmory -|-unboost|p2a: Skarmory|evasion|1 -|-sideend|p2: Lady bug|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -|move|p2a: Skarmory|Whirlwind|p1a: Skarmory -|drag|p1a: Heatran|Heatran, M|385/385 -| -|turn|148 -|chat|blarajan|yes -|chat|OU Mew|y -|chat|Laga|it is -|chat|Stinson|ah cool -|chat|THE_IRON_KENYAN|this is a team friendly -|chat|Imanalt|fucking destroyed -|chat|chieliee|i feel sorry for the teammates counting every pp on every move -|chat|Soulgazer|nb -|chat|Pwnemon|lol tik -|chat|blarajan|cntl f -|chat|Imanalt|not like its hard chieliee, ctrl+f -| -|switch|p2a: Gyarados|Gyarados, F|366/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Lava Plume|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|309/394 -| -|-heal|p2a: Gyarados|333/394|[from] item: Leftovers -|turn|149 -|chat|jumpluff|ah chieliee gets it -|chat|THE_IRON_KENYAN|how does anyone win this -|chat|chieliee|yeah but if roost, you have to fliter out which is ur roost and which is the others -|chat|THE_IRON_KENYAN|first guy to run out of aroma therapies -| -|switch|p2a: Nidoqueen|Nidoqueen, F|280/384 -|switch|p1a: Quagsire|Quagsire, M|311/393 -| -|-heal|p2a: Nidoqueen|304/384|[from] item: Leftovers -|-heal|p1a: Quagsire|335/393|[from] item: Leftovers -|turn|150 -|chat|chieliee|and spectator talk -|chat|Valentine|stone -|chat|myzozoa|they should double switch more -|chat|myzozoa|conserve that pp -|chat|Stone_Cold22|val -|chat|jdarden|even ctrl _f is irritating when so many moves are shared -|chat|Valentine|im on shoddy -|chat|Valentine|leggo -|chat|Stone_Cold22|shoddy is for fegs -|chat|Valentine|halo -|chat|Imanalt|nah tik lb probably willl eventually win when venu runs out of synths -|chat|Stone_Cold22|do ppl still use it -|chat|Stone_Cold22|? -| -|switch|p2a: Blissey|Blissey, F|631/688 -|move|p1a: Quagsire|Earthquake|p2a: Blissey -|-damage|p2a: Blissey|450/688 -| -|-heal|p2a: Blissey|493/688|[from] item: Leftovers -|-heal|p1a: Quagsire|359/393|[from] item: Leftovers -|turn|151 -|chat|Stone_Cold22|lol -|chat|Valentine|nah -|chat|Valentine|http://i.imgur.com/MBLvpS5.png -|chat|Stone_Cold22|o -|chat|Imanalt|running out of aromatherapies woudl take fucking forever -| -|switch|p2a: Clefable|Clefable, M|394/394 -|switch|p1a: Chansey|Chansey, F|416/660 -| -|turn|152 -|chat|blarajan|what does big clefable do -| -|switch|p2a: Nidoqueen|Nidoqueen, F|304/384 -|move|p1a: Chansey|Toxic|p2a: Nidoqueen -|-fail|p2a: Nidoqueen -| -|-heal|p2a: Nidoqueen|328/384|[from] item: Leftovers -|turn|153 -|chat|blarajan|let us see -|chat|blarajan|nothing -|chat|myzozoa|it takes 2 pp just to get rid of 1 aromatherapy -|chat|blarajan|it does nothing -|chat|Imanalt|rofl 4 switches last 3 turns -|chat|myzozoa|so it isnt efficient -|chat|LonelyNess|lol -|chat|THE_IRON_KENYAN|this is worst than vertical videos -| -|switch|p2a: Gyarados|Gyarados, F|333/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Chansey -|-unboost|p1a: Chansey|atk|1 -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 -| -|-heal|p2a: Gyarados|357/394|[from] item: Leftovers -|turn|154 -|chat|THE_IRON_KENYAN|worse -|chat|Annoyer|clefable hasnt made a move yet -| -|switch|p1a: Quagsire|Quagsire, M|359/393 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p2a: Gyarados|381/394|[from] item: Leftovers -|-heal|p1a: Quagsire|383/393|[from] item: Leftovers -|turn|155 -| -|switch|p2a: Blissey|Blissey, F|493/688 -|move|p1a: Quagsire|Scald|p2a: Blissey -|-damage|p2a: Blissey|445/688 -| -|-heal|p2a: Blissey|488/688|[from] item: Leftovers -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|156 -|chat|george182|whats the spl record, for turns? -|chat|jumpluff|700+ -|chat|jumpluff|in gsc -|chat|LonelyNess|714 -|chat|jumpluff|several times -|chat|Imanalt|well george182, theres gsc -|chat|LonelyNess|Colchonero vs. Floppy -|chat|LonelyNess|and -|chat|chieliee|this might very well break that -| -|move|p2a: Blissey|Seismic Toss|p1a: Quagsire -|-damage|p1a: Quagsire|293/393 -|move|p1a: Quagsire|Toxic|p2a: Blissey|[miss] -|-miss|p1a: Quagsire|p2a: Blissey -| -|-heal|p2a: Blissey|531/688|[from] item: Leftovers -|-heal|p1a: Quagsire|317/393|[from] item: Leftovers -|turn|157 -|chat|Stinson|gsc is brutal -|chat|LonelyNess|Colchonero vs. Earthworm -|chat|LonelyNess|both were 714 -|chat|Imanalt|nah i dont see this going more than about 450 -| -|move|p2a: Blissey|Toxic|p1a: Quagsire -|-status|p1a: Quagsire|tox -|move|p1a: Quagsire|Recover|p1a: Quagsire -|-heal|p1a: Quagsire|393/393 tox -| -|-heal|p2a: Blissey|574/688|[from] item: Leftovers -|-damage|p1a: Quagsire|369/393 tox|[from] psn -|turn|158 -|chat|jumpluff|floppy vs. conflict was quite high as well -|chat|Hugendugen|714? -|chat|jumpluff|also gsc -| -|switch|p2a: Abomasnow|Abomasnow, M|336/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-weather|Hail -|switch|p1a: Chansey|Chansey, F|660/660 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Chansey|619/660|[from] Hail -|turn|159 -|chat|Hugendugen|didnt that get beat -|chat|LonelyNess|no Hugendugen -|chat|LonelyNess|it got tied -| -|move|p1a: Chansey|Aromatherapy|p1a: Chansey -|-cureteam|p1a: Chansey|[from] move: Aromatherapy -|move|p2a: Abomasnow|Wood Hammer|p1a: Chansey -|-damage|p1a: Chansey|339/660 -|-damage|p2a: Abomasnow|244/384|[from] recoil|[of] p1a: Chansey -| -|-weather|Hail|[upkeep] -|-damage|p1a: Chansey|298/660|[from] Hail -|turn|160 -|chat|THE_IRON_KENYAN|leech seed that moverfucker -|chat|Hugendugen|ah -|chat|LonelyNess|literally the same number of turns -|chat|blarajan|ABOMASNOW -|chat|myzozoa|damage -|chat|LonelyNess|it was pretty funny -|chat|THE_IRON_KENYAN|weeed hammer -|chat|Imanalt|PLAYS -|chat|Laga|ah the wood hammer -|chat|Hugendugen|lol -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Abomasnow|Leech Seed|p1a: Heatran -|-start|p1a: Heatran|move: Leech Seed -| -|-weather|Hail|[upkeep] -|-damage|p1a: Heatran|361/385|[from] Hail -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|-damage|p1a: Heatran|337/385|[from] Leech Seed|[of] p2a: Abomasnow -|-heal|p2a: Abomasnow|292/384|[silent] -|turn|161 -|chat|dekzeh|big damage -|chat|THE_IRON_KENYAN|another play -| -|switch|p2a: Nidoqueen|Nidoqueen, F|328/384 -|move|p1a: Heatran|Stealth Rock|p2a: Nidoqueen -|-sidestart|p2: Lady bug|move: Stealth Rock -| -|-weather|Hail|[upkeep] -|-damage|p1a: Heatran|313/385|[from] Hail -|-damage|p2a: Nidoqueen|304/384|[from] Hail -|-heal|p1a: Heatran|337/385|[from] item: Leftovers -|-heal|p2a: Nidoqueen|328/384|[from] item: Leftovers -|-damage|p1a: Heatran|289/385|[from] Leech Seed|[of] p2a: Nidoqueen -|-heal|p2a: Nidoqueen|376/384|[silent] -|turn|162 -|chat|OU Mew|play time -|chat|jumpluff|does nobody else find the intricateness of hard stall games entrancing -| -|switch|p1a: Chansey|Chansey, F|298/660 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-weather|none -|-heal|p2a: Nidoqueen|384/384|[from] item: Leftovers -|turn|163 -|chat|Imanalt|lol -|chat|Pwnemon|the switch to skarm is real -|chat|Pwnemon|nope -|chat|jumpluff|its like theyre actually battling on top of an icy mountain -|chat|blarajan|NO -|chat|Pwnemon|weak -|chat|jumpluff|enduring the elements -|chat|jdarden|lol -|chat|jumpluff|he who focuses less loses -|chat|THE_IRON_KENYAN|plays like this, is what makes stall able to stand -| -|switch|p2a: Skarmory|Skarmory, M|289/334 -|-damage|p2a: Skarmory|248/334|[from] Stealth Rock -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|628/660 -| -|turn|164 -|chat|THE_IRON_KENYAN|so nobody hands themself with their own waistband -|chat|Hugendugen|whoever reads more of the battle chat -|chat|Hugendugen|loses -|chat|jumpluff|lol -| -|switch|p1a: Skarmory|Skarmory, F|253/334 -|move|p2a: Skarmory|Whirlwind|p1a: Skarmory -|drag|p1a: Heatran|Heatran, M|289/385 -| -|-heal|p1a: Heatran|313/385|[from] item: Leftovers -|turn|165 -|chat|myzozoa|lol -|chat|Soulgazer|nb -|chat|Imanalt|bh games are so mcuh more interesting because despite being the same length one turn can swing the game a lot more, so meh -| -|switch|p2a: Gyarados|Gyarados, F|381/394 -|-damage|p2a: Gyarados|283/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Lava Plume|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|221/394 -| -|-heal|p2a: Gyarados|245/394|[from] item: Leftovers -|-heal|p1a: Heatran|337/385|[from] item: Leftovers -|turn|166 -| -|switch|p1a: Skarmory|Skarmory, F|253/334 -|move|p2a: Gyarados|Earthquake|p1a: Skarmory -|-immune|p1a: Skarmory|[msg] -| -|-heal|p2a: Gyarados|269/394|[from] item: Leftovers -|-heal|p1a: Skarmory|273/334|[from] item: Leftovers -|turn|167 -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Blissey|Blissey, F|574/688 -|-damage|p2a: Blissey|488/688|[from] Stealth Rock -| -|-heal|p1a: Skarmory|293/334|[from] item: Leftovers -|-heal|p2a: Blissey|531/688|[from] item: Leftovers -|turn|168 -|chat|the pdc show|lol -| -|move|p1a: Skarmory|Defog|p2a: Blissey -|-unboost|p2a: Blissey|evasion|1 -|-sideend|p2: Lady bug|Stealth Rock|[from] move: Defog|[of] p2a: Blissey -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -|move|p2a: Blissey|Seismic Toss|p1a: Skarmory -|-damage|p1a: Skarmory|193/334 -| -|-heal|p1a: Skarmory|213/334|[from] item: Leftovers -|-heal|p2a: Blissey|574/688|[from] item: Leftovers -|turn|169 -| -|switch|p1a: Chansey|Chansey, F|628/660 -|switch|p2a: Nidoqueen|Nidoqueen, F|384/384 -| -|turn|170 -| -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|284/384 -| -|-heal|p2a: Nidoqueen|308/384|[from] item: Leftovers -|turn|171 -| -|switch|p1a: Venusaur|Venusaur, M|194/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -|move|p2a: Nidoqueen|Flamethrower|p1a: Venusaur -|-supereffective|p1a: Venusaur -|-damage|p1a: Venusaur|144/364 -| -|-heal|p2a: Nidoqueen|332/384|[from] item: Leftovers -|turn|172 -| -|move|p2a: Nidoqueen|Flamethrower|p1a: Venusaur -|-crit|p1a: Venusaur -|-supereffective|p1a: Venusaur -|-damage|p1a: Venusaur|78/364 -|move|p1a: Venusaur|Synthesis|p1a: Venusaur -|-heal|p1a: Venusaur|260/364 -| -|-heal|p2a: Nidoqueen|356/384|[from] item: Leftovers -|turn|173 -|chat|chieliee|no burn smh -|chat|THE_IRON_KENYAN|i thought that flamethrower was gonna KO -|chat|Annoyer|the crit -|chat|Laga|some day the brn will hapen -|chat|Pwnemon|bs crit -|chat|Soulgazer|crit mattered -| -|switch|p1a: Chansey|Chansey, F|628/660 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|380/384|[from] item: Leftovers -|turn|174 -|chat|Soulgazer|jk -|chat|Arcticblast|>crit -|chat|Arcticblast|>18% -| -|move|p2a: Nidoqueen|Flamethrower|p1a: Chansey -|-damage|p1a: Chansey|590/660 -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|280/384 -| -|-heal|p2a: Nidoqueen|304/384|[from] item: Leftovers -|turn|175 -|chat|Pwnemon|>super effective -|chat|Treecko|Laga: some day the brn will hapen -|chat|Hot N Cold|> using moves in this battle -| -|move|p2a: Nidoqueen|Flamethrower|p1a: Chansey -|-damage|p1a: Chansey|552/660 -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|204/384 -| -|-heal|p2a: Nidoqueen|228/384|[from] item: Leftovers -|turn|176 -|chat|Treecko|it's sheer force isn't it? -|chat|Arcticblast|but Pwnemon, Thick Fat -|chat|Joim|dat thick fat -|chat|Laga|wait -|chat|jdarden|yes -|chat|Laga|fuck -|chat|jdarden|lol -|chat|Treecko|lol -|chat|Pwnemon|hes jk treevko -|chat|chieliee|oh -|chat|THE_IRON_KENYAN|this is how all pokemon matches should be -|chat|Pwnemon|lol -|chat|chieliee|right -| -|switch|p2a: Skarmory|Skarmory, M|248/334 -|move|p1a: Chansey|Seismic Toss|p2a: Skarmory -|-damage|p2a: Skarmory|148/334 -|-damage|p1a: Chansey|442/660|[from] item: Rocky Helmet|[of] p2a: Skarmory -| -|turn|177 -|chat|Pwnemon|or was he -|chat|Laga|damn that is lame -|chat|Pwnemon|thought he was -|chat|Joim|this is a true competition amongst minds -| -|switch|p1a: Skarmory|Skarmory, F|213/334 -|move|p2a: Skarmory|Roost|p2a: Skarmory -|-heal|p2a: Skarmory|315/334 -| -|-heal|p1a: Skarmory|233/334|[from] item: Leftovers -|turn|178 -|chat|Stone_Cold22|lady bug -| -|switch|p2a: Nidoqueen|Nidoqueen, F|228/384 -|move|p1a: Skarmory|Defog|p2a: Nidoqueen -|-unboost|p2a: Nidoqueen|evasion|1 -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -| -|-heal|p2a: Nidoqueen|252/384|[from] item: Leftovers -|-heal|p1a: Skarmory|253/334|[from] item: Leftovers -|turn|179 -|chat|Treecko|this actually is really fun to watch ngl -|chat|Arcticblast|and bladders, Joim -|chat|Stone_Cold22|r u arab? -|chat|Arcticblast|he who pisses first loses -|chat|Pwnemon|and caffiene supplements -| -|switch|p1a: Chansey|Chansey, F|442/660 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|276/384|[from] item: Leftovers -|turn|180 -|chat|Laga|yeah the activity -|chat|Laga|is sexy -|chat|PttP|who shall choke on the dick of shame first -| -|switch|p2a: Clefable|Clefable, M|394/394 -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 -| -|turn|181 -|chat|Laga|way better than 6 mins per turn -|chat|dekzeh|THE CLEFABLE IS HERE -|chat|Joim|ablast didn't you learn anything from south park -| -|switch|p2a: Skarmory|Skarmory, M|315/334 -|switch|p1a: Heatran|Heatran, M|337/385 -| -|-heal|p1a: Heatran|361/385|[from] item: Leftovers -|turn|182 -|chat|THE_IRON_KENYAN|has clefable used 1 move yet -|chat|Pwnemon|way less than 6% per turn -|chat|blarajan|pttp i thought you kept the dick of shame in your room so no one else could choke on it -|chat|Soulgazer|ah -|chat|Laga|the clefable has left -|chat|Soulgazer|not bad -| -|switch|p2a: Gyarados|Gyarados, F|269/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Lava Plume|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|212/394 -|-status|p2a: Gyarados|brn -| -|-heal|p2a: Gyarados|236/394 brn|[from] item: Leftovers -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|-damage|p2a: Gyarados|187/394 brn|[from] brn -|turn|183 -|chat|Joim|you can pee on your place -|chat|Pwnemon|lol blara -|chat|THE_IRON_KENYAN|the plays -| -|switch|p1a: Skarmory|Skarmory, F|253/334 -|move|p2a: Gyarados|Earthquake|p1a: Skarmory -|-immune|p1a: Skarmory|[msg] -| -|-heal|p2a: Gyarados|211/394 brn|[from] item: Leftovers -|-heal|p1a: Skarmory|273/334|[from] item: Leftovers -|-damage|p2a: Gyarados|162/394 brn|[from] brn -|turn|184 -|chat|Pwnemon|crit bb callin now -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Skarmory|Defog|p2a: Gyarados -|-unboost|p2a: Gyarados|evasion|1 -|-sideend|p1: Lord Elyis|Toxic Spikes|[from] move: Defog|[of] p1a: Skarmory -| -|-heal|p1a: Skarmory|293/334|[from] item: Leftovers -|turn|185 -|chat|Stone_Cold22|scarf bb -|chat|Joim|defog is op -| -|switch|p2a: Nidoqueen|Nidoqueen, F|276/384 -|switch|p1a: Quagsire|Quagsire, M|369/393 -| -|-heal|p2a: Nidoqueen|300/384|[from] item: Leftovers -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|186 -|chat|Pwnemon|that was not a bb -|chat|Pwnemon|:| -|chat|jumpluff|cowardly bird -| -|move|p2a: Nidoqueen|Sludge Wave|p1a: Quagsire -|-resisted|p1a: Quagsire -|-damage|p1a: Quagsire|318/393 -|move|p1a: Quagsire|Scald|p2a: Nidoqueen -|-supereffective|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|138/384 -|-status|p2a: Nidoqueen|brn -| -|-heal|p2a: Nidoqueen|162/384 brn|[from] item: Leftovers -|-heal|p1a: Quagsire|342/393|[from] item: Leftovers -|-damage|p2a: Nidoqueen|114/384 brn|[from] brn -|turn|187 -|chat|Soulgazer|ah -|chat|Hot N Cold|. -|chat|Laga|:O -|chat|blarajan|shit -|chat|THE_IRON_KENYAN|the plays -|chat|Soulgazer|not bad -|chat|jdarden|shiiit -|chat|Pwnemon|uh oh -|chat|Nachos|a turn of events. -|chat|Annoyer|first ko?? -|chat|Pwnemon|no -| -|switch|p2a: Blissey|Blissey, F|574/688 -|switch|p1a: Gliscor|Gliscor, M|275/353 -| -|-heal|p2a: Blissey|617/688|[from] item: Leftovers -|-activate|p1a: Gliscor|item: Toxic Orb -|-status|p1a: Gliscor|tox -|turn|188 -|chat|Pwnemon|lol -|chat|Joim|damn -|chat|Joim|poor nidoqueen -|chat|THE_IRON_KENYAN|ill bet you a hundred dollars clefairy has wish -|chat|Soulgazer|ah -|chat|Soulgazer|not bad -|chat|Soulgazer|Oo -|chat|Pwnemon|gyara can take gliscor all day -|chat|THE_IRON_KENYAN|wish protect ice pinch aroma -| -|switch|p1a: Heatran|Heatran, M|385/385 -|switch|p2a: Gyarados|Gyarados, F|394/394 slp -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -| -|turn|189 -| -|switch|p1a: Quagsire|Quagsire, M|342/393 -|cant|p2a: Gyarados|slp -| -|-heal|p1a: Quagsire|366/393|[from] item: Leftovers -|turn|190 -| -|switch|p2a: Blissey|Blissey, F|617/688 -|move|p1a: Quagsire|Scald|p2a: Blissey -|-damage|p2a: Blissey|566/688 -| -|-heal|p2a: Blissey|609/688|[from] item: Leftovers -|-heal|p1a: Quagsire|390/393|[from] item: Leftovers -|turn|191 -|chat|Laga|man this is going to get to 250 turns -|chat|Laga|without a single death isn't it -|chat|Pwnemon|y -|chat|blarajan|why are you still watching -|chat|blarajan|genuinely -|chat|blarajan|shut up -| -|move|p2a: Blissey|Aromatherapy|p2a: Blissey -|-cureteam|p2a: Blissey|[from] move: Aromatherapy -|move|p1a: Quagsire|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -| -|-heal|p2a: Blissey|652/688 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|-damage|p2a: Blissey|609/688 tox|[from] psn -|turn|192 -|chat|PttP|still faster than the NU / RU / Doubles games -|chat|Laga|blarajan why so mad -|chat|THE_IRON_KENYAN|still isnt as bad as LC right guys -|chat|THE_IRON_KENYAN|huehue -|chat|Pwnemon|doubles games are fast -|chat|Pwnemon|with jake -|chat|Biosci|because you guys -| -|switch|p1a: Gliscor|Gliscor, M|275/353 tox -|move|p2a: Blissey|Toxic|p1a: Gliscor|[miss] -|-miss|p2a: Blissey|p1a: Gliscor -| -|-heal|p2a: Blissey|652/688 tox|[from] item: Leftovers -|-heal|p1a: Gliscor|319/353 tox|[from] ability: Poison Heal -|-damage|p2a: Blissey|566/688 tox|[from] psn -|turn|193 -|chat|Laga|did I ever say that I didn't enjoy watching -|chat|bro fist|still better than lc -|chat|Biosci|keep bitching -|chat|blarajan|huehue -| -|switch|p1a: Heatran|Heatran, M|385/385 -|switch|p2a: Skarmory|Skarmory, M|315/334 -| -|turn|194 -|chat|Stone_Cold22|elyis -|chat|Stone_Cold22|it's 12:48 in lady bugs time zone -| -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Stealth Rock|p2a: Gyarados -|-sidestart|p2: Lady bug|move: Stealth Rock -| -|turn|195 -|chat|Stone_Cold22|stall this out till the nigga has to go to bed -| -|switch|p1a: Skarmory|Skarmory, F|293/334 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p1a: Skarmory|313/334|[from] item: Leftovers -|turn|196 -|chat|Annoyer|lol -|chat|gr8astard|rofl -|chat|Stone_Cold22|it's like 1am there -|chat|Pwnemon|lol -|chat|gr8astard|what a veteran -|chat|jumpluff|does anyone remember what setrack did to rey -| -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-damage|p1a: Skarmory|223/334 -|cant|p1a: Skarmory|flinch -| -|-heal|p1a: Skarmory|243/334|[from] item: Leftovers -|turn|197 -|chat|Stone_Cold22|mommy gonna be coming soon -|chat|Pwnemon|hes still playin better -|chat|Annoyer|strategy/ -|chat|Pwnemon|sad -|chat|chimpact|uh oh -|chat|blarajan|LGIIIIIIIII -| -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-damage|p1a: Skarmory|149/334 -|move|p1a: Skarmory|Roost|p1a: Skarmory -|-heal|p1a: Skarmory|316/334 -| -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|198 -|chat|reyscarface|go for gold -|chat|THE_IRON_KENYAN|that gyarados is playing angry -|chat|Joim|outplayed -|chat|reyscarface|no gold -|chat|Soulgazer|blara -|chat|Soulgazer|im here -| -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-damage|p1a: Skarmory|240/334 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Nidoqueen|Nidoqueen, F|114/384 -|-damage|p2a: Nidoqueen|90/384|[from] Stealth Rock -| -|-heal|p2a: Nidoqueen|114/384|[from] item: Leftovers -|-heal|p1a: Skarmory|260/334|[from] item: Leftovers -|turn|199 -|chat|Soulgazer|he wont flinch to death -|chat|jumpluff|rey do you remembre -|chat|Soulgazer|*-* -|chat|jumpluff|the setrack incident -|chat|Aqualouis|o -|chat|reyscarface|yes what a cunt -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|move|p2a: Nidoqueen|Flamethrower|p1a: Quagsire -|-resisted|p1a: Quagsire -|-damage|p1a: Quagsire|346/393 -| -|-heal|p2a: Nidoqueen|138/384|[from] item: Leftovers -|-heal|p1a: Quagsire|370/393|[from] item: Leftovers -|turn|200 -|chat|Aqualouis|we can play gsc on PO -|chat|jumpluff|indeed -|chat|Aqualouis|i didnt know -|chat|OU Mew|no burn hax -| -|switch|p2a: Skarmory|Skarmory, M|315/334 -|-damage|p2a: Skarmory|274/334|[from] Stealth Rock -|move|p1a: Quagsire|Scald|p2a: Skarmory -|-damage|p2a: Skarmory|187/334 -| -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|201 -|chat|Soulgazer|mew,, -|chat|Soulgazer|sheer force -|chat|LonelyNess|it's sheer force you morans there is no burn / poison hax -| -|move|p2a: Skarmory|Defog|p1a: Quagsire -|-unboost|p1a: Quagsire|evasion|1 -|-sideend|p2: Lady bug|Stealth Rock|[from] move: Defog|[of] p2a: Skarmory -|move|p1a: Quagsire|Scald|p2a: Skarmory -|-damage|p2a: Skarmory|112/334 -|-status|p2a: Skarmory|brn -| -|-damage|p2a: Skarmory|71/334 brn|[from] brn -|turn|202 -|chat|OU Mew|hax -|chat|chieliee|who is setrack -|chat|Soulgazer|,, -|chat|Soulgazer|ah -|chat|Soulgazer|nb -|chat|Soulgazer|n_n -|chat|Stone_Cold22|the legend -|chat|chimpact|ouch -| -|switch|p2a: Abomasnow|Abomasnow, M|292/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-weather|Hail -|move|p1a: Quagsire|Earthquake|p2a: Abomasnow -|-resisted|p2a: Abomasnow -|-damage|p2a: Abomasnow|247/384 -| -|-weather|Hail|[upkeep] -|-damage|p1a: Quagsire|369/393|[from] Hail -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|203 -|chat|jumpluff|the ultimate proponent of playing to win -|chat|blarajan|no burn hax huh lonelyness -|chat|THE_IRON_KENYAN|i remember setrack -|chat|jumpluff|the cacturne boss -|chat|LonelyNess|YOU KNOW WHAT I MEANT BLARA -|chat|jumpluff|once he deliberately exploited shoddy to timer stall rey out because rey had to go to bed -|chat|Pwnemon|show the eq -| -|switch|p1a: Heatran|Heatran, M|385/385 -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|370/394|[from] Hail -|-damage|p1a: Heatran|361/385|[from] Hail -|-heal|p2a: Gyarados|394/394|[from] item: Leftovers -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|turn|204 -|chat|jumpluff|i forget what the TDs ruled on that one -|chat|jumpluff|i think they ruled in rey's favour -|chat|reyscarface|they gave me win and banned setrack -| -|switch|p2a: Blissey|Blissey, F|566/688 -|switch|p1a: Quagsire|Quagsire, M|393/393 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Blissey|523/688|[from] Hail -|-damage|p1a: Quagsire|369/393|[from] Hail -|-heal|p2a: Blissey|566/688|[from] item: Leftovers -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|205 -|chat|Pwnemon|lol -|chat|jumpluff|ah lol -|chat|THE_IRON_KENYAN|what is reys bed time 8 -|chat|OU Mew|no byrn -|chat|jumpluff|everyone was like yo go to bed the TDs will give you the win -| -|move|p2a: Blissey|Aromatherapy|p2a: Blissey -|-cureteam|p2a: Blissey|[from] move: Aromatherapy -|move|p1a: Quagsire|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -| -|-weather|Hail|[upkeep] -|-damage|p2a: Blissey|523/688 tox|[from] Hail -|-damage|p1a: Quagsire|369/393|[from] Hail -|-heal|p2a: Blissey|566/688 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|-damage|p2a: Blissey|523/688 tox|[from] psn -|turn|206 -|chat|blarajan|[15:50] <@Aqualouis> is it xy ? -|chat|jumpluff|but rey was refusing to give in for awhile -|chat|blarajan|lol -|chat|blarajan|aqualouis couldn't tell this was xy -|chat|jumpluff|man it feels weird to talk about timer glitches nowadays -| -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Quagsire -|-unboost|p1a: Quagsire|atk|1 -|move|p1a: Quagsire|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-weather|none -|turn|207 -|chat|reyscarface|well kenyan i was 14 back then -|chat|blarajan|until he saw mega aboma -|chat|reyscarface|and it was 2 am or something -|chat|Pwnemon|lol -|chat|jumpluff|you could just stall people infinitely then -| -|switch|p2a: Clefable|Clefable, M|394/394 -|move|p1a: Quagsire|Scald|p2a: Clefable -|-damage|p2a: Clefable|327/394 -| -|-heal|p2a: Clefable|351/394|[from] item: Leftovers -|turn|208 -|chat|jumpluff|due to shoddy being bugged -|chat|Annoyer|clef -|chat|Soulgazer|fable -|chat|Pwnemon|CLEFABLE -|chat|THE_IRON_KENYAN|shoddy battle was a great place -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Clefable|Wish|p2a: Clefable -| -|-heal|p2a: Clefable|375/394|[from] item: Leftovers -|turn|209 -|chat|Pwnemon|time for wish -|chat|jumpluff|that was like the main thing mods had to deal with -|chat|THE_IRON_KENYAN|I KNEW IT -|chat|Annoyer|nooo -|chat|OU Mew|YES -|chat|Pwnemon|lol -| -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Roar|p2a: Gyarados -|drag|p2a: Clefable|Clefable, M|375/394 -| -|-heal|p2a: Clefable|394/394|[from] move: Wish|[wisher] Clefable -|turn|210 -|chat|blarajan|DANG -|chat|Pwnemon|aw -|chat|Soulgazer|ah not bad -|chat|Nachos|lol -|chat|reyscarface|damn BS -|chat|jumpluff|ouchhhh -|chat|THE_IRON_KENYAN|BACK TO CLEFABE -| -|move|p1a: Heatran|Stealth Rock|p2a: Clefable -|-sidestart|p2: Lady bug|move: Stealth Rock -|move|p2a: Clefable|Wish|p2a: Clefable -| -|turn|211 -|chat|Soulgazer|2ez -|chat|Pwnemon|we had a 1/3 -| -|move|p1a: Heatran|Lava Plume|p2a: Clefable -|-damage|p2a: Clefable|276/394 -|move|p2a: Clefable|Calm Mind|p2a: Clefable -|-boost|p2a: Clefable|spa|1 -|-boost|p2a: Clefable|spd|1 -| -|-heal|p2a: Clefable|394/394|[from] move: Wish|[wisher] Clefable -|turn|212 -|chat|Annoyer|getting it -|chat|Laga|:O -|chat|Pwnemon|yes -| -|move|p2a: Clefable|Wish|p2a: Clefable -|move|p1a: Heatran|Roar|p2a: Clefable -|drag|p2a: Skarmory|Skarmory, M|71/334 -|-damage|p2a: Skarmory|30/334|[from] Stealth Rock -| -|turn|213 -|chat|LonelyNess|HE'S GOING FOR IT -|chat|Soulgazer|ah the set -|chat|OU Mew|no burn hax -|chat|SoulWind|LOL -|chat|Pwnemon|oh god -|chat|chieliee|uh oh -|chat|Soulgazer|hello skarm -|chat|PttP|went for it -|chat|SoulWind|there it is -|chat|SoulWind|first kill -|chat|reyscarface|das some bs -|chat|Soulgazer|LOL -|chat|Annoyer|protect -|chat|Sapientia|protect if real -|chat|Pwnemon|game over -|chat|Pwnemon|shit -|chat|Joim|wow -|chat|Afro Smash|:] -|chat|reyscarface|ya this shits gonna be gay -|chat|Nachos|:] -|chat|Soulgazer|:] -|chat|reyscarface|#notworth -|chat|Stone_Cold22|the legend -|chat|Stone_Cold22|#worth -|chat|Joim|that roar -|chat|Arcticblast|even if he had Protect it wouldn't work, Roar bypasses it -|chat|Soulgazer|amazing play -|chat|Arcticblast|in gen 6 -|chat|Nachos|that was a yung roar -|chat|Joim|but wish -|chat|blarajan|yes because he's going to roar now -|chat|Laga|ablast if he roosts on a roar -|chat|chieliee|if he keeps it alive he can force the oppo to not defog yn -| -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-damage|p2a: Gyarados|296/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Lava Plume|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|237/394 -|-status|p2a: Gyarados|brn -| -|-heal|p2a: Gyarados|394/394 brn|[from] move: Wish|[wisher] Clefable -|-damage|p2a: Gyarados|345/394 brn|[from] brn -|turn|214 -|chat|Arcticblast|true -|chat|Soulgazer|chielee stop ghosting in chat -|chat|PttP|should have roared -|chat|Pwnemon|oo chielee is geniius -|chat|Afro Smash|based elyis -|chat|Soulgazer|and nice hburn -|chat|Laga|but that would be dumb -|chat|PttP|1/5th cahnce -|chat|Soulgazer|:D -|chat|PttP|of getting skarm -|chat|PttP|take. -| -|switch|p2a: Nidoqueen|Nidoqueen, F|138/384 -|-damage|p2a: Nidoqueen|114/384|[from] Stealth Rock -|switch|p1a: Quagsire|Quagsire, M|393/393 -| -|-heal|p2a: Nidoqueen|138/384|[from] item: Leftovers -|turn|215 -|chat|Soulgazer|nice switch -|chat|Arcticblast|well Skarm is dead no questions asked -|chat|Soulgazer|Oo -|chat|Soulgazer|oO -| -|switch|p2a: Blissey|Blissey, F|523/688 -|-damage|p2a: Blissey|437/688|[from] Stealth Rock -|move|p1a: Quagsire|Scald|p2a: Blissey -|-damage|p2a: Blissey|394/688 -| -|-heal|p2a: Blissey|437/688|[from] item: Leftovers -|turn|216 -|chat|THE_IRON_KENYAN|im gonna guess the nidoqueen has rapid spin tbh -|chat|Afro Smash|not is he forces elyis to defog -|chat|Arcticblast|true -| -|switch|p1a: Gliscor|Gliscor, M|319/353 tox -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-heal|p2a: Blissey|688/688 -| -|-heal|p1a: Gliscor|353/353 tox|[from] ability: Poison Heal -|turn|217 -|chat|Arcticblast|yes TIK -|chat|chieliee|yeah but idk how that is gonna happen -|chat|Arcticblast|Rapid Spin Nidoqueen -|chat|Pwnemon|lol -|chat|Arcticblast|new -|chat|chieliee|he has no sr weak mons -|chat|Arcticblast|meta -| -|move|p1a: Gliscor|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -|move|p2a: Blissey|Aromatherapy|p2a: Blissey -|-cureteam|p2a: Blissey|[from] move: Aromatherapy -| -|turn|218 -|chat|Pwnemon|lol -|chat|chieliee|and can get rid of tspikes with venu -| -|move|p1a: Gliscor|Earthquake|p2a: Blissey -|-damage|p2a: Blissey|475/688 -|move|p2a: Blissey|Seismic Toss|p1a: Gliscor -|-damage|p1a: Gliscor|253/353 tox -| -|-heal|p2a: Blissey|518/688|[from] item: Leftovers -|-heal|p1a: Gliscor|297/353 tox|[from] ability: Poison Heal -|turn|219 -|chat|Stone_Cold22|NICE PREDIC -|chat|Soulgazer|was it worth -| -|move|p1a: Gliscor|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -|move|p2a: Blissey|Seismic Toss|p1a: Gliscor -|-damage|p1a: Gliscor|197/353 tox -| -|-heal|p2a: Blissey|561/688 tox|[from] item: Leftovers -|-heal|p1a: Gliscor|241/353 tox|[from] ability: Poison Heal -|-damage|p2a: Blissey|518/688 tox|[from] psn -|turn|220 -| -|switch|p2a: Gyarados|Gyarados, F|345/394 -|-damage|p2a: Gyarados|247/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Gliscor -|-unboost|p1a: Gliscor|atk|1 -|move|p1a: Gliscor|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p2a: Gyarados|271/394|[from] item: Leftovers -|-heal|p1a: Gliscor|285/353 tox|[from] ability: Poison Heal -|turn|221 -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p2a: Gyarados|295/394|[from] item: Leftovers -|turn|222 -|chat|OU Mew|222 -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|361/394 slp -| -|-heal|p2a: Gyarados|385/394 slp|[from] item: Leftovers -|turn|223 -|chat|Soulgazer|gratz for informing us mew -| -|switch|p1a: Skarmory|Skarmory, F|260/334 -|cant|p2a: Gyarados|slp -| -|-heal|p2a: Gyarados|394/394 slp|[from] item: Leftovers -|-heal|p1a: Skarmory|280/334|[from] item: Leftovers -|turn|224 -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Blissey|Blissey, F|518/688 -|-damage|p2a: Blissey|432/688|[from] Stealth Rock -| -|-heal|p1a: Skarmory|300/334|[from] item: Leftovers -|-heal|p2a: Blissey|475/688|[from] item: Leftovers -|turn|225 -|chat|chieliee|no skarm! -| -|move|p1a: Skarmory|Brave Bird|p2a: Blissey -|-damage|p2a: Blissey|253/688 -|-damage|p1a: Skarmory|227/334|[from] recoil|[of] p2a: Blissey -|move|p2a: Blissey|Seismic Toss|p1a: Skarmory -|-damage|p1a: Skarmory|127/334 -| -|-heal|p1a: Skarmory|147/334|[from] item: Leftovers -|-heal|p2a: Blissey|296/688|[from] item: Leftovers -|turn|226 -| -|move|p1a: Skarmory|Roost|p1a: Skarmory -|-heal|p1a: Skarmory|314/334 -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-heal|p2a: Blissey|640/688 -| -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|-heal|p2a: Blissey|683/688|[from] item: Leftovers -|turn|227 -|chat|THE_IRON_KENYAN|id have used flamethrower tbh -|chat|Pwnemon|never skarm .trl -|chat|jumpluff|i hate the spelling change -| -|switch|p1a: Chansey|Chansey, F|660/660 -|switch|p2a: Gyarados|Gyarados, F|394/394 slp -|-damage|p2a: Gyarados|296/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Chansey -|-unboost|p1a: Chansey|atk|1 -| -|-heal|p2a: Gyarados|320/394 slp|[from] item: Leftovers -|turn|228 -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p2a: Gyarados|344/394|[from] item: Leftovers -|turn|229 -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|313/394 -|-status|p2a: Gyarados|brn -| -|-heal|p2a: Gyarados|337/394 brn|[from] item: Leftovers -|-damage|p2a: Gyarados|288/394 brn|[from] brn -|turn|230 -|chat|Soulgazer|nb -|chat|Arcticblast|turn 230 -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|342/393 -|move|p1a: Quagsire|Toxic|p2a: Gyarados -|-fail|p2a: Gyarados -| -|-heal|p2a: Gyarados|312/394 brn|[from] item: Leftovers -|-heal|p1a: Quagsire|366/393|[from] item: Leftovers -|-damage|p2a: Gyarados|263/394 brn|[from] brn -|turn|231 -|chat|blarajan|solid dommage -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|359/394 slp -| -|-heal|p2a: Gyarados|383/394 slp|[from] item: Leftovers -|-heal|p1a: Quagsire|390/393|[from] item: Leftovers -|turn|232 -|chat|Pwnemon|lol -|chat|Afro Smash|wheres the water absorb -|chat|Soulgazer|amazing domage -| -|switch|p2a: Clefable|Clefable, M|394/394 -|-damage|p2a: Clefable|345/394|[from] Stealth Rock -|switch|p1a: Skarmory|Skarmory, F|334/334 -| -|-heal|p2a: Clefable|369/394|[from] item: Leftovers -|turn|233 -| -|move|p2a: Clefable|Wish|p2a: Clefable -|move|p1a: Skarmory|Whirlwind|p2a: Clefable -|drag|p2a: Abomasnow|Abomasnow, M|247/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-damage|p2a: Abomasnow|151/384|[from] Stealth Rock -|-weather|Hail -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|314/334|[from] Hail -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|234 -| -|move|p2a: Abomasnow|Protect|p2a: Abomasnow -|-singleturn|p2a: Abomasnow|Protect -|move|p1a: Skarmory|Brave Bird|p2a: Abomasnow -|-activate|p2a: Abomasnow|Protect -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|314/334|[from] Hail -|-heal|p2a: Abomasnow|348/384|[from] move: Wish|[wisher] Clefable -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|235 -|chat|THE_IRON_KENYAN|blizzard? -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Abomasnow|Leech Seed|p1a: Heatran -|-start|p1a: Heatran|move: Leech Seed -| -|-weather|Hail|[upkeep] -|-damage|p1a: Heatran|361/385|[from] Hail -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|-damage|p1a: Heatran|337/385|[from] Leech Seed|[of] p2a: Abomasnow -|-heal|p2a: Abomasnow|384/384|[silent] -|turn|236 -|chat|Stone_Cold22|nice predic lady bug! -|chat|Pwnemon|place -|chat|THE_IRON_KENYAN|seed -| -|move|p2a: Abomasnow|Protect|p2a: Abomasnow -|-singleturn|p2a: Abomasnow|Protect -|move|p1a: Heatran|Roar|p2a: Abomasnow -|drag|p2a: Gyarados|Gyarados, F|383/394 slp -|-damage|p2a: Gyarados|285/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|261/394 slp|[from] Hail -|-damage|p1a: Heatran|313/385|[from] Hail -|-heal|p2a: Gyarados|285/394 slp|[from] item: Leftovers -|-heal|p1a: Heatran|337/385|[from] item: Leftovers -|-damage|p1a: Heatran|289/385|[from] Leech Seed|[of] p2a: Gyarados -|-heal|p2a: Gyarados|333/394 slp|[silent] -|turn|237 -|chat|Lady bug|huh -|chat|PttP|those damn 6th gen mechanics -|chat|Texas Cloverleaf|new mech -|chat|Treecko|goes through protect now lol -|chat|blarajan|protect doesn't block roar -|chat|Soulgazer|lovely mechs -|chat|Lady bug|i see -| -|switch|p2a: Clefable|Clefable, M|369/394 -|-damage|p2a: Clefable|320/394|[from] Stealth Rock -|switch|p1a: Quagsire|Quagsire, M|390/393 -| -|-weather|none -|-heal|p2a: Clefable|344/394|[from] item: Leftovers -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|238 -| -|move|p2a: Clefable|Protect|p2a: Clefable -|-singleturn|p2a: Clefable|Protect -|move|p1a: Quagsire|Toxic|p2a: Clefable -|-activate|p2a: Clefable|Protect -| -|-heal|p2a: Clefable|368/394|[from] item: Leftovers -|turn|239 -| -|move|p2a: Clefable|Wish|p2a: Clefable -|move|p1a: Quagsire|Toxic|p2a: Clefable -|-status|p2a: Clefable|tox -| -|-heal|p2a: Clefable|392/394 tox|[from] item: Leftovers -|-damage|p2a: Clefable|368/394 tox|[from] psn -|turn|240 -|chat|Pwnemon|where is the eq -|chat|Pwnemon|on aboma -|chat|Pwnemon|:| -| -|switch|p2a: Abomasnow|Abomasnow, M|384/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-damage|p2a: Abomasnow|288/384|[from] Stealth Rock -|-weather|Hail -|move|p1a: Quagsire|Scald|p2a: Abomasnow -|-resisted|p2a: Abomasnow -|-damage|p2a: Abomasnow|258/384 -|-status|p2a: Abomasnow|brn -| -|-weather|Hail|[upkeep] -|-damage|p1a: Quagsire|369/393|[from] Hail -|-heal|p2a: Abomasnow|384/384 brn|[from] move: Wish|[wisher] Clefable -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|-damage|p2a: Abomasnow|336/384 brn|[from] brn -|turn|241 -|chat|Arcticblast|it's revealed every move -|chat|Arcticblast|so nowhere -|chat|Soulgazer|ah -|chat|Soulgazer|not bad -|chat|Soulgazer|*-* -|chat|Pwnemon|9.9 -| -|switch|p1a: Heatran|Heatran, M|289/385 -|move|p2a: Abomasnow|Leech Seed|p1a: Heatran -|-start|p1a: Heatran|move: Leech Seed -| -|-weather|Hail|[upkeep] -|-damage|p1a: Heatran|265/385|[from] Hail -|-heal|p1a: Heatran|289/385|[from] item: Leftovers -|-damage|p1a: Heatran|241/385|[from] Leech Seed|[of] p2a: Abomasnow -|-heal|p2a: Abomasnow|384/384 brn|[silent] -|-damage|p2a: Abomasnow|336/384 brn|[from] brn -|turn|242 -| -|switch|p1a: Chansey|Chansey, F|660/660 -|switch|p2a: Blissey|Blissey, F|683/688 -|-damage|p2a: Blissey|597/688|[from] Stealth Rock -| -|-weather|Hail|[upkeep] -|-damage|p2a: Blissey|554/688|[from] Hail -|-damage|p1a: Chansey|619/660|[from] Hail -|-heal|p2a: Blissey|597/688|[from] item: Leftovers -|turn|243 -| -|move|p2a: Blissey|Aromatherapy|p2a: Blissey -|-cureteam|p2a: Blissey|[from] move: Aromatherapy -|move|p1a: Chansey|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -| -|-weather|Hail|[upkeep] -|-damage|p2a: Blissey|554/688 tox|[from] Hail -|-damage|p1a: Chansey|578/660|[from] Hail -|-heal|p2a: Blissey|597/688 tox|[from] item: Leftovers -|-damage|p2a: Blissey|554/688 tox|[from] psn -|turn|244 -|chat|THE_IRON_KENYAN|arcticblast why arent i allowed to rap -|chat|Afro Smash|:] -| -|switch|p2a: Gyarados|Gyarados, F|333/394 -|-damage|p2a: Gyarados|235/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Chansey -|-unboost|p1a: Chansey|atk|1 -|move|p1a: Chansey|Seismic Toss|p2a: Gyarados -|-damage|p2a: Gyarados|135/394 -| -|-weather|none -|-heal|p2a: Gyarados|159/394|[from] item: Leftovers -|turn|245 -|chat|Arcticblast|this battle is a jazz piece -|chat|Arcticblast|no rapping -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -| -|turn|246 -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|cant|p2a: Gyarados|slp -| -|turn|247 -|chat|THE_IRON_KENYAN|http://www.youtube.com/watch?v=M4sEcIHG0Yc -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Clefable|Clefable, M|368/394 -|-damage|p2a: Clefable|319/394|[from] Stealth Rock -| -|-heal|p2a: Clefable|343/394|[from] item: Leftovers -|turn|248 -| -|switch|p1a: Heatran|Heatran, M|241/385 -|move|p2a: Clefable|Calm Mind|p2a: Clefable -|-boost|p2a: Clefable|spa|1 -|-boost|p2a: Clefable|spd|1 -| -|-heal|p1a: Heatran|265/385|[from] item: Leftovers -|-heal|p2a: Clefable|367/394|[from] item: Leftovers -|turn|249 -|chat|Treecko|oOOO)o0o0oo -| -|move|p2a: Clefable|Wish|p2a: Clefable -|move|p1a: Heatran|Roar|p2a: Clefable -|drag|p2a: Blissey|Blissey, F|554/688 -|-damage|p2a: Blissey|468/688|[from] Stealth Rock -| -|-heal|p1a: Heatran|289/385|[from] item: Leftovers -|-heal|p2a: Blissey|511/688|[from] item: Leftovers -|turn|250 -| -|switch|p2a: Gyarados|Gyarados, F|394/394 slp -|-damage|p2a: Gyarados|296/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Lava Plume|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|236/394 slp -| -|-heal|p2a: Gyarados|394/394 slp|[from] move: Wish|[wisher] Clefable -|-heal|p1a: Heatran|313/385|[from] item: Leftovers -|turn|251 -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|turn|252 -|chat|MarceloDK|... -| -|move|p2a: Gyarados|Earthquake|p1a: Quagsire -|-damage|p1a: Quagsire|323/393 -|move|p1a: Quagsire|Toxic|p2a: Gyarados -|-status|p2a: Gyarados|tox -| -|-heal|p1a: Quagsire|347/393|[from] item: Leftovers -|-damage|p2a: Gyarados|370/394 tox|[from] psn -|turn|253 -|chat|chieliee|250 without death, technically speaking -|chat|chieliee|whoever predicted that was right -|chat|MarceloDK|how is this turn 251 -|chat|jumpluff|laga -|chat|MarceloDK|with 12 pokemons -| -|move|p2a: Gyarados|Earthquake|p1a: Quagsire -|-crit|p1a: Quagsire -|-damage|p1a: Quagsire|241/393 -|move|p1a: Quagsire|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p2a: Gyarados|394/394 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|265/393|[from] item: Leftovers -|-damage|p2a: Gyarados|346/394 tox|[from] psn -|turn|254 -|chat|Pwnemon|crit -|chat|Pwnemon|bs -|chat|MarceloDK|?_______________? -|chat|Soulgazer|quag eating it up -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Quagsire|Recover|p1a: Quagsire -|-heal|p1a: Quagsire|393/393 -| -|-heal|p2a: Gyarados|370/394 tox|[from] item: Leftovers -|-damage|p2a: Gyarados|298/394 tox|[from] psn -|turn|255 -|chat|Hugendugen|http://youtubedoubler.com/?video1=AYw7eJYadco&start1=10&video2=HMnrl0tmd3k&start2=0&authorName=rainy+mood -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|300/393 -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|266/394 tox -| -|-heal|p2a: Gyarados|290/394 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|324/393|[from] item: Leftovers -|-damage|p2a: Gyarados|194/394 tox|[from] psn -|turn|256 -|chat|Hot N Cold|preserve 6-6 imo -|chat|Pwnemon|lol -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p1a: Quagsire|348/393|[from] item: Leftovers -|turn|257 -|chat|THE_IRON_KENYAN|why isnt gyara eating its chesto berry -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|cant|p2a: Gyarados|slp -| -|turn|258 -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Abomasnow|Abomasnow, M|336/384 -|-formechange|p2a: Abomasnow|Abomasnow-Mega -|-damage|p2a: Abomasnow|240/384|[from] Stealth Rock -|-weather|Hail -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|314/334|[from] Hail -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|259 -|chat|Arcticblast|it only has the leftovers TIK -|chat|Biosci|it doesn't have any leftover -|chat|Stone_Cold22|TIK, don't reveal items plz. It's disrespectful -| -|move|p1a: Skarmory|Brave Bird|p2a: Abomasnow -|-supereffective|p2a: Abomasnow -|-damage|p2a: Abomasnow|0 fnt -|-damage|p1a: Skarmory|255/334|[from] recoil|[of] p2a: Abomasnow -|faint|p2a: Abomasnow -| -|-weather|Hail|[upkeep] -|-damage|p1a: Skarmory|235/334|[from] Hail -|-heal|p1a: Skarmory|255/334|[from] item: Leftovers -|chat|Arcticblast|FIRST BLOOD -|chat|jumpluff|nooo -|chat|Biosci|oooooo -|chat|Pwnemon|oh -|chat|jumpluff|the aboma -|chat|Annoyer|first ko. -|chat|chieliee|KILL -|chat|Nachos|Damn. -|chat|Pwnemon|shit -|chat|MarceloDK|ah -|chat|Soulgazer|THE BLOOD -| -|switch|p2a: Gyarados|Gyarados, F|394/394 slp -|-damage|p2a: Gyarados|296/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Skarmory -|-unboost|p1a: Skarmory|atk|1 -|turn|260 -|chat|Hot N Cold|No. -|chat|Hot N Cold|:( -| -|switch|p1a: Quagsire|Quagsire, M|348/393 -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|272/394|[from] Hail -|-damage|p1a: Quagsire|324/393|[from] Hail -|-heal|p2a: Gyarados|296/394|[from] item: Leftovers -|-heal|p1a: Quagsire|348/393|[from] item: Leftovers -|turn|261 -|chat|MarceloDK|lady bug bring a lot of skarm counters -|chat|MarceloDK|I see -|chat|Joim|damn... -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|363/394 slp -| -|-weather|Hail|[upkeep] -|-damage|p2a: Gyarados|339/394 slp|[from] Hail -|-damage|p1a: Quagsire|324/393|[from] Hail -|-heal|p2a: Gyarados|363/394 slp|[from] item: Leftovers -|-heal|p1a: Quagsire|348/393|[from] item: Leftovers -|turn|262 -|chat|Pwnemon|4-6 -|chat|Pwnemon|can he pull out?? -|chat|PKLaurel|Elyis is @lovely? -| -|switch|p1a: Skarmory|Skarmory, F|255/334 -|cant|p2a: Gyarados|slp -| -|-weather|none -|-heal|p2a: Gyarados|387/394 slp|[from] item: Leftovers -|-heal|p1a: Skarmory|275/334|[from] item: Leftovers -|turn|263 -|chat|chieliee|its technically still 5-6! -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Skarmory|Skarmory, M|30/334 -|-damage|p2a: Skarmory|0 fnt|[from] Stealth Rock -|faint|p2a: Skarmory -| -|-heal|p1a: Skarmory|295/334|[from] item: Leftovers -|chat|Annoyer|nto aynmore -|chat|chieliee|ok -|chat|Stone_Cold22|ded -|chat|Pwnemon|not anymore -|chat|Laga|nice timing -|chat|chieliee|not anymore -|chat|IFM|ded -|chat|Treecko|o0o00000ooo -|chat|Joim|whirlwind and roar -| -|switch|p2a: Clefable|Clefable, M|367/394 -|-damage|p2a: Clefable|318/394|[from] Stealth Rock -|turn|264 -|chat|Joim|are cheating -|chat|Soulgazer|SECOND BLOOD -| -|switch|p1a: Chansey|Chansey, F|578/660 -|move|p2a: Clefable|Wish|p2a: Clefable -| -|-heal|p2a: Clefable|342/394|[from] item: Leftovers -|turn|265 -|chat|chieliee|shits going down -|chat|THE_IRON_KENYAN|ez -|chat|Pwnemon|does nido live stoss????? -|chat|Biosci|now you must kill the queen used by the king -|c|+PttP|!data nidoqueen -|c|~|/data-pokemon Nidoqueen - -|chat|MarceloDK|n -|chat|PttP|n; -| -|switch|p2a: Nidoqueen|Nidoqueen, F|138/384 -|-damage|p2a: Nidoqueen|114/384|[from] Stealth Rock -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|14/384 -| -|-heal|p2a: Nidoqueen|211/384|[from] move: Wish|[wisher] Clefable -|-heal|p2a: Nidoqueen|235/384|[from] item: Leftovers -|turn|266 -|chat|chieliee|y -|chat|Pwnemon|liars -|chat|PttP|i was right -| -|switch|p2a: Blissey|Blissey, F|511/688 -|-damage|p2a: Blissey|425/688|[from] Stealth Rock -|move|p1a: Chansey|Seismic Toss|p2a: Blissey -|-damage|p2a: Blissey|325/688 -| -|-heal|p2a: Blissey|368/688|[from] item: Leftovers -|turn|267 -|chat|MarceloDK|.trl -| -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -|move|p1a: Chansey|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -| -|-heal|p2a: Blissey|411/688 tox|[from] item: Leftovers -|-damage|p2a: Blissey|368/688 tox|[from] psn -|-damage|p1a: Chansey|537/660 tox|[from] psn -|turn|268 -|chat|Hugendugen|what a toxic family relationship -| -|switch|p1a: Gliscor|Gliscor, M|285/353 tox -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-heal|p2a: Blissey|688/688 tox -| -|-heal|p1a: Gliscor|329/353 tox|[from] ability: Poison Heal -|-damage|p2a: Blissey|602/688 tox|[from] psn -|turn|269 -|chat|PKLaurel|i see you hugen -| -|switch|p2a: Gyarados|Gyarados, F|387/394 slp -|-damage|p2a: Gyarados|289/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Gliscor -|-unboost|p1a: Gliscor|atk|1 -|move|p1a: Gliscor|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p2a: Gyarados|313/394 slp|[from] item: Leftovers -|-heal|p1a: Gliscor|353/353 tox|[from] ability: Poison Heal -|turn|270 -|chat|Pwnemon|wow hugenwoody -| -|switch|p1a: Quagsire|Quagsire, M|348/393 -|switch|p2a: Clefable|Clefable, M|342/394 -|-damage|p2a: Clefable|293/394|[from] Stealth Rock -| -|-heal|p2a: Clefable|317/394|[from] item: Leftovers -|-heal|p1a: Quagsire|372/393|[from] item: Leftovers -|turn|271 -| -|switch|p2a: Gyarados|Gyarados, F|313/394 slp -|-damage|p2a: Gyarados|215/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Quagsire -|-unboost|p1a: Quagsire|atk|1 -|move|p1a: Quagsire|Toxic|p2a: Gyarados -|-fail|p2a: Gyarados -| -|-heal|p2a: Gyarados|239/394 slp|[from] item: Leftovers -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|272 -| -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|364/394 slp -| -|-heal|p2a: Gyarados|388/394 slp|[from] item: Leftovers -|turn|273 -| -|switch|p1a: Skarmory|Skarmory, F|295/334 -|cant|p2a: Gyarados|slp -| -|-heal|p2a: Gyarados|394/394 slp|[from] item: Leftovers -|-heal|p1a: Skarmory|315/334|[from] item: Leftovers -|turn|274 -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Blissey|Blissey, F|602/688 -|-damage|p2a: Blissey|516/688|[from] Stealth Rock -| -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|-heal|p2a: Blissey|559/688|[from] item: Leftovers -|turn|275 -|chat|THE_IRON_KENYAN|skarm is gonna run out of whirlwinds soon -| -|move|p1a: Skarmory|Brave Bird|p2a: Blissey -|-damage|p2a: Blissey|333/688 -|-damage|p1a: Skarmory|259/334|[from] recoil|[of] p2a: Blissey -|move|p2a: Blissey|Seismic Toss|p1a: Skarmory -|-damage|p1a: Skarmory|159/334 -| -|-heal|p1a: Skarmory|179/334|[from] item: Leftovers -|-heal|p2a: Blissey|376/688|[from] item: Leftovers -|turn|276 -|chat|Pwnemon|now that you cant bring in lb's skarm -| -|move|p1a: Skarmory|Roost|p1a: Skarmory -|-heal|p1a: Skarmory|334/334 -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-heal|p2a: Blissey|688/688 -| -|turn|277 -|chat|Pwnemon|i dont see much point in giving that move a whiel -| -|switch|p1a: Chansey|Chansey, F|537/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|437/660 -| -|turn|278 -|chat|Pwnemon|whirl* dammit -|chat|Pwnemon|ruined -| -|switch|p2a: Clefable|Clefable, M|317/394 -|-damage|p2a: Clefable|268/394|[from] Stealth Rock -|move|p1a: Chansey|Toxic|p2a: Clefable -|-status|p2a: Clefable|tox -| -|-heal|p2a: Clefable|292/394 tox|[from] item: Leftovers -|-damage|p2a: Clefable|268/394 tox|[from] psn -|turn|279 -Pwnemon was muted by Arcticblast for 7 minutes. (ruined) -|unlink|pwnemon -| -|switch|p1a: Heatran|Heatran, M|313/385 -|move|p2a: Clefable|Wish|p2a: Clefable -| -|-heal|p1a: Heatran|337/385|[from] item: Leftovers -|-heal|p2a: Clefable|292/394 tox|[from] item: Leftovers -|-damage|p2a: Clefable|244/394 tox|[from] psn -|turn|280 -|chat|MarceloDK|lol -Pwnemon was unmuted by Arcticblast. -|chat|Soulgazer|thanks ablast -| -|switch|p2a: Nidoqueen|Nidoqueen, F|235/384 -|-damage|p2a: Nidoqueen|211/384|[from] Stealth Rock -|move|p1a: Heatran|Roar|p2a: Nidoqueen -|drag|p2a: Blissey|Blissey, F|688/688 -|-damage|p2a: Blissey|602/688|[from] Stealth Rock -| -|-heal|p2a: Blissey|688/688|[from] move: Wish|[wisher] Clefable -|-heal|p1a: Heatran|361/385|[from] item: Leftovers -|turn|281 -|chat|Treecko|nooo -|chat|Soulgazer|mute him back -|chat|Soulgazer|what are you doing -| -|switch|p1a: Gliscor|Gliscor, M|353/353 tox -|move|p2a: Blissey|Aromatherapy|p2a: Blissey -|-cureteam|p2a: Blissey|[from] move: Aromatherapy -| -|turn|282 -|chat|chieliee|7 minutes that's nothing -| -|switch|p2a: Gyarados|Gyarados, F|394/394 -|-damage|p2a: Gyarados|296/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Gliscor -|-unboost|p1a: Gliscor|atk|1 -|move|p1a: Gliscor|Toxic|p2a: Gyarados -|-status|p2a: Gyarados|tox -| -|-heal|p2a: Gyarados|320/394 tox|[from] item: Leftovers -|-damage|p2a: Gyarados|296/394 tox|[from] psn -|turn|283 -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|switch|p2a: Blissey|Blissey, F|688/688 -|-damage|p2a: Blissey|602/688|[from] Stealth Rock -| -|-heal|p2a: Blissey|645/688|[from] item: Leftovers -|turn|284 -| -|switch|p1a: Chansey|Chansey, F|437/660 -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -| -|-heal|p2a: Blissey|688/688|[from] item: Leftovers -|-damage|p1a: Chansey|396/660 tox|[from] psn -|turn|285 -| -|switch|p2a: Nidoqueen|Nidoqueen, F|211/384 -|-damage|p2a: Nidoqueen|187/384|[from] Stealth Rock -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 tox -| -|-heal|p2a: Nidoqueen|211/384|[from] item: Leftovers -|-damage|p1a: Chansey|578/660 tox|[from] psn -|turn|286 -|chat|THE_IRON_KENYAN|focus punch -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Quagsire -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|235/384|[from] item: Leftovers -|turn|287 -| -|switch|p2a: Gyarados|Gyarados, F|296/394 tox -|-damage|p2a: Gyarados|198/394 tox|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Quagsire -|-unboost|p1a: Quagsire|atk|1 -|move|p1a: Quagsire|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p2a: Gyarados|222/394 tox|[from] item: Leftovers -|-damage|p2a: Gyarados|198/394 tox|[from] psn -|turn|288 -| -|switch|p1a: Venusaur|Venusaur, M|260/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -| -|turn|289 -| -|switch|p2a: Blissey|Blissey, F|688/688 -|-damage|p2a: Blissey|602/688|[from] Stealth Rock -|move|p1a: Venusaur|Giga Drain|p2a: Blissey -|-damage|p2a: Blissey|533/688 -|-heal|p1a: Venusaur|295/364|[from] drain|[of] p2a: Blissey -| -|-heal|p2a: Blissey|576/688|[from] item: Leftovers -|turn|290 -| -|move|p1a: Venusaur|Earthquake|p2a: Blissey -|-damage|p2a: Blissey|444/688 -|move|p2a: Blissey|Seismic Toss|p1a: Venusaur -|-damage|p1a: Venusaur|195/364 -| -|-heal|p2a: Blissey|487/688|[from] item: Leftovers -|turn|291 -|chat|Stone_Cold22|lady_bug, your mom callin u -|chat|Stone_Cold22|wondering why ur up -|chat|Stone_Cold22|shoud prob forfeit -| -|switch|p1a: Gliscor|Gliscor, M|353/353 tox -|move|p2a: Blissey|Seismic Toss|p1a: Gliscor -|-damage|p1a: Gliscor|253/353 tox -| -|-heal|p2a: Blissey|530/688|[from] item: Leftovers -|-heal|p1a: Gliscor|297/353 tox|[from] ability: Poison Heal -|turn|292 -| -|switch|p2a: Gyarados|Gyarados, F|394/394 slp -|-damage|p2a: Gyarados|296/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Gliscor -|-unboost|p1a: Gliscor|atk|1 -|move|p1a: Gliscor|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p2a: Gyarados|320/394 slp|[from] item: Leftovers -|-heal|p1a: Gliscor|341/353 tox|[from] ability: Poison Heal -|turn|293 -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|cant|p2a: Gyarados|slp -| -|-heal|p2a: Gyarados|344/394 slp|[from] item: Leftovers -|turn|294 -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Brave Bird|p2a: Gyarados -|-damage|p2a: Gyarados|251/394 slp -|-damage|p1a: Skarmory|303/334|[from] recoil|[of] p2a: Gyarados -| -|-heal|p2a: Gyarados|275/394 slp|[from] item: Leftovers -|-heal|p1a: Skarmory|323/334|[from] item: Leftovers -|turn|295 -| -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-crit|p1a: Skarmory -|-damage|p1a: Skarmory|220/334 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Blissey|Blissey, F|530/688 -|-damage|p2a: Blissey|444/688|[from] Stealth Rock -| -|-heal|p1a: Skarmory|240/334|[from] item: Leftovers -|-heal|p2a: Blissey|487/688|[from] item: Leftovers -|turn|296 -|chat|Pwnemon|mattered -|chat|Pwnemon|:| -| -|switch|p1a: Chansey|Chansey, F|578/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|478/660 -| -|-heal|p2a: Blissey|530/688|[from] item: Leftovers -|turn|297 -| -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -|move|p1a: Chansey|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -| -|-heal|p2a: Blissey|573/688 tox|[from] item: Leftovers -|-damage|p2a: Blissey|530/688 tox|[from] psn -|-damage|p1a: Chansey|437/660 tox|[from] psn -|turn|298 -| -|switch|p2a: Clefable|Clefable, M|244/394 -|-damage|p2a: Clefable|195/394|[from] Stealth Rock -|switch|p1a: Venusaur|Venusaur, M|195/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -| -|-heal|p2a: Clefable|219/394|[from] item: Leftovers -|turn|299 -|chat|Hugendugen|what a toxic family relationship -|chat|THE_IRON_KENYAN|lol -|chat|Heist|i think PO should be recommended for battles over 300 turns -| -|move|p2a: Clefable|Protect|p2a: Clefable -|-singleturn|p2a: Clefable|Protect -|move|p1a: Venusaur|Sludge Bomb|p2a: Clefable -|-activate|p2a: Clefable|Protect -| -|-heal|p2a: Clefable|243/394|[from] item: Leftovers -|turn|300 -|chat|Pwnemon|u already did that joke -|chat|PKLaurel|god dammit hugen -|chat|Soulgazer|venusaur *-* -|chat|Heist|took like 2 mins for this battle to load -| -|switch|p2a: Blissey|Blissey, F|530/688 -|-damage|p2a: Blissey|444/688|[from] Stealth Rock -|move|p1a: Venusaur|Sludge Bomb|p2a: Blissey -|-damage|p2a: Blissey|350/688 -| -|-heal|p2a: Blissey|393/688|[from] item: Leftovers -|turn|301 -|chat|Soulgazer|lo heist -|chat|Soulgazer|lo* -|chat|Afro Smash|po should be reccomended for everything -| -|move|p1a: Venusaur|Synthesis|p1a: Venusaur -|-heal|p1a: Venusaur|364/364 -|move|p2a: Blissey|Seismic Toss|p1a: Venusaur -|-damage|p1a: Venusaur|264/364 -| -|-heal|p2a: Blissey|436/688|[from] item: Leftovers -|turn|302 -|chat|Soulgazer|lol -|chat|Soulgazer|oml -| -|switch|p1a: Gliscor|Gliscor, M|341/353 tox -|switch|p2a: Nidoqueen|Nidoqueen, F|235/384 -|-damage|p2a: Nidoqueen|211/384|[from] Stealth Rock -| -|-heal|p2a: Nidoqueen|235/384|[from] item: Leftovers -|-heal|p1a: Gliscor|353/353 tox|[from] ability: Poison Heal -|turn|303 -|chat|Pwnemon|afro smash ur a fuckin noob -|chat|Arcticblast|>PO for BW and XY -|chat|Pwnemon|imo -|chat|PKLaurel|plays -|chat|Afro Smash|:] -| -|switch|p2a: Gyarados|Gyarados, F|275/394 -|-damage|p2a: Gyarados|177/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Gliscor -|-unboost|p1a: Gliscor|atk|1 -|move|p1a: Gliscor|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p2a: Gyarados|201/394|[from] item: Leftovers -|turn|304 -|chat|Laga|wow pwnemon don't talk about RU master afro smash like that -| -|switch|p1a: Skarmory|Skarmory, F|240/334 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p2a: Gyarados|225/394|[from] item: Leftovers -|-heal|p1a: Skarmory|260/334|[from] item: Leftovers -|turn|305 -|chat|Hugendugen|if Afro Smash says so, then we're off to PO -|chat|Pwnemon|im sorry -|chat|Pwnemon|i still believe -|chat|Laga|his name is a billion times more epic than you -|chat|Pwnemon|:]]]] -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|299/393 -| -|-heal|p2a: Gyarados|249/394|[from] item: Leftovers -|-heal|p1a: Quagsire|323/393|[from] item: Leftovers -|turn|306 -|chat|Soulgazer|LAGA. -|chat|Afro Smash|:]]]] -| -|move|p2a: Gyarados|Earthquake|p1a: Quagsire -|-damage|p1a: Quagsire|248/393 -|move|p1a: Quagsire|Toxic|p2a: Gyarados -|-status|p2a: Gyarados|tox -| -|-heal|p2a: Gyarados|273/394 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|272/393|[from] item: Leftovers -|-damage|p2a: Gyarados|249/394 tox|[from] psn -|turn|307 -|chat|Soulgazer|:]] -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Recover|p1a: Quagsire -|-heal|p1a: Quagsire|393/393 -| -|turn|308 -| -|switch|p1a: Skarmory|Skarmory, F|260/334 -|cant|p2a: Gyarados|slp -| -|-heal|p1a: Skarmory|280/334|[from] item: Leftovers -|turn|309 -|chat|PttP|16:02 lol i seriously cant see a way 16:02 that lady bug loses -|chat|PttP|-,- -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Blissey|Blissey, F|436/688 -|-damage|p2a: Blissey|350/688|[from] Stealth Rock -| -|-heal|p1a: Skarmory|300/334|[from] item: Leftovers -|-heal|p2a: Blissey|393/688|[from] item: Leftovers -|turn|310 -|chat|Soulgazer|?_? -|chat|PKLaurel|I can't see a way that lady bug wins... -| -|move|p1a: Skarmory|Brave Bird|p2a: Blissey -|-damage|p2a: Blissey|170/688 -|-damage|p1a: Skarmory|226/334|[from] recoil|[of] p2a: Blissey -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-heal|p2a: Blissey|514/688 -| -|-heal|p1a: Skarmory|246/334|[from] item: Leftovers -|-heal|p2a: Blissey|557/688|[from] item: Leftovers -|turn|311 -|chat|Pwnemon|that was before aboma died -|chat|PKLaurel|Elyis has rocks -|chat|chieliee|i cant se a way that either of these win -|chat|Pwnemon|but uh -|chat|Soulgazer|elyis wrecks -|chat|Pwnemon|pklaurel with the advice -|chat|Pwnemon|as always -| -|switch|p1a: Chansey|Chansey, F|437/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|337/660 -| -|-heal|p2a: Blissey|600/688|[from] item: Leftovers -|turn|312 -|chat|MikeDecIsHere|311 turns -|chat|Pwnemon|n__n -|chat|MikeDecIsHere|damn -| -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -|move|p1a: Chansey|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -| -|-heal|p2a: Blissey|643/688 tox|[from] item: Leftovers -|-damage|p2a: Blissey|600/688 tox|[from] psn -|-damage|p1a: Chansey|296/660 tox|[from] psn -|turn|313 -|chat|Soulgazer|mike is here -|chat|Soulgazer|:o -| -|switch|p2a: Nidoqueen|Nidoqueen, F|235/384 -|-damage|p2a: Nidoqueen|211/384|[from] Stealth Rock -|switch|p1a: Gliscor|Gliscor, M|353/353 tox -| -|-heal|p2a: Nidoqueen|235/384|[from] item: Leftovers -|turn|314 -|chat|MikeDecIsHere|Soulgazer, we need to play for randbats -|chat|MikeDecIsHere|! -|chat|Soulgazer|ooo -|chat|Soulgazer|after this -| -|switch|p2a: Gyarados|Gyarados, F|394/394 slp -|-damage|p2a: Gyarados|296/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Gliscor -|-unboost|p1a: Gliscor|atk|1 -|move|p1a: Gliscor|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p2a: Gyarados|320/394 slp|[from] item: Leftovers -|turn|315 -|chat|MikeDecIsHere|ya -|chat|Pwnemon|what about our dubs battle soulgazer -|chat|Pwnemon|i am hurt -| -|switch|p1a: Skarmory|Skarmory, F|246/334 -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p2a: Gyarados|344/394|[from] item: Leftovers -|-heal|p1a: Skarmory|266/334|[from] item: Leftovers -|turn|316 -|chat|Soulgazer|fight me now -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|305/393 -| -|-heal|p2a: Gyarados|368/394|[from] item: Leftovers -|-heal|p1a: Quagsire|329/393|[from] item: Leftovers -|turn|317 -|chat|Soulgazer|._. -|chat|Pwnemon|disrespectful -|chat|Laga|I want to see soulgazer win vs pwnemon in dubs -|chat|Pwnemon|to the gentlemen battling -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|361/394 slp -| -|-heal|p2a: Gyarados|385/394 slp|[from] item: Leftovers -|-heal|p1a: Quagsire|353/393|[from] item: Leftovers -|turn|318 -|chat|Hugendugen|what a chump, not running water absorb quagsire -|chat|jdarden|pwnejohn -| -|switch|p2a: Nidoqueen|Nidoqueen, F|235/384 -|-damage|p2a: Nidoqueen|211/384|[from] Stealth Rock -|switch|p1a: Skarmory|Skarmory, F|266/334 -| -|-heal|p2a: Nidoqueen|235/384|[from] item: Leftovers -|-heal|p1a: Skarmory|286/334|[from] item: Leftovers -|turn|319 -|chat|Soulgazer|lol -|chat|Pwnemon|plays -|chat|Soulgazer|i can have both of them on the same screen -|chat|Pwnemon|the flamethrower is real -| -|switch|p1a: Quagsire|Quagsire, M|353/393 -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Quagsire -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -| -|-heal|p2a: Nidoqueen|259/384|[from] item: Leftovers -|-heal|p1a: Quagsire|377/393|[from] item: Leftovers -|turn|320 -|chat|Laga|preferably hrough ridiculous hax -|chat|Soulgazer|dw -| -|switch|p2a: Blissey|Blissey, F|600/688 -|-damage|p2a: Blissey|514/688|[from] Stealth Rock -|switch|p1a: Venusaur|Venusaur, M|264/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -| -|-heal|p2a: Blissey|557/688|[from] item: Leftovers -|turn|321 -|chat|Sir|i think that Po is better than PS -| -|switch|p1a: Chansey|Chansey, F|296/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|196/660 -| -|-heal|p2a: Blissey|600/688|[from] item: Leftovers -|turn|322 -|chat|PKLaurel|i didn't know that we were playing GSC -| -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|526/660 tox -| -|-heal|p2a: Blissey|643/688|[from] item: Leftovers -|-damage|p1a: Chansey|485/660 tox|[from] psn -|turn|323 -|chat|Arcticblast|idk Sir I think they could go either way -|chat|Pwnemon|we arent, gsc doesnt have SR -|chat|Pwnemon|:| -|chat|Sir|yea u got me -|chat|Texas Cloverleaf|gsc is faster -| -|switch|p2a: Gyarados|Gyarados, F|385/394 slp -|-damage|p2a: Gyarados|287/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Chansey -|-unboost|p1a: Chansey|atk|1 -|switch|p1a: Gliscor|Gliscor, M|353/353 tox -| -|-heal|p2a: Gyarados|311/394 slp|[from] item: Leftovers -|turn|324 -|chat|dekzeh|Sir who do you think is winning this -|chat|Texas Cloverleaf|also laurel you're 240 turns laste -|chat|Sir|idk -|chat|Texas Cloverleaf|with that joke -|chat|Sir|could go either way -|chat|Joim|gsc has based spikes, one stack -| -|switch|p1a: Skarmory|Skarmory, F|286/334 -|switch|p2a: Nidoqueen|Nidoqueen, F|259/384 -|-damage|p2a: Nidoqueen|235/384|[from] Stealth Rock -| -|-heal|p2a: Nidoqueen|259/384|[from] item: Leftovers -|-heal|p1a: Skarmory|306/334|[from] item: Leftovers -|turn|325 -|chat|PKLaurel|i joined at turn 250 :( -| -|switch|p1a: Quagsire|Quagsire, M|377/393 -|move|p2a: Nidoqueen|Flamethrower|p1a: Quagsire -|-resisted|p1a: Quagsire -|-damage|p1a: Quagsire|324/393 -| -|-heal|p2a: Nidoqueen|283/384|[from] item: Leftovers -|-heal|p1a: Quagsire|348/393|[from] item: Leftovers -|turn|326 -|chat|Sir|this is worse than LC -| -|switch|p1a: Venusaur|Venusaur, M|264/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Nidoqueen|Flamethrower|p1a: Venusaur -|-supereffective|p1a: Venusaur -|-damage|p1a: Venusaur|220/364 -| -|-heal|p2a: Nidoqueen|307/384|[from] item: Leftovers -|turn|327 -| -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Venusaur -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -|move|p1a: Venusaur|Giga Drain|p2a: Nidoqueen -|-crit|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|132/384 -|-heal|p1a: Venusaur|308/364|[from] drain|[of] p2a: Nidoqueen -| -|-heal|p2a: Nidoqueen|156/384|[from] item: Leftovers -|turn|328 -|chat|Pwnemon|no burn??? -|chat|Afro Smash|shluuurp -| -|switch|p2a: Blissey|Blissey, F|643/688 -|-damage|p2a: Blissey|557/688|[from] Stealth Rock -|move|p1a: Venusaur|Giga Drain|p2a: Blissey -|-damage|p2a: Blissey|485/688 -|-heal|p1a: Venusaur|344/364|[from] drain|[of] p2a: Blissey -| -|-heal|p2a: Blissey|528/688|[from] item: Leftovers -|turn|329 -|chat|Texas Cloverleaf|da crits -|chat|Sir|the game is advancing -|chat|Pwnemon|o wow im late -|chat|Pwnemon|by multiple turns -| -|switch|p1a: Gliscor|Gliscor, M|353/353 tox -|move|p2a: Blissey|Seismic Toss|p1a: Gliscor -|-damage|p1a: Gliscor|253/353 tox -| -|-heal|p2a: Blissey|571/688|[from] item: Leftovers -|-heal|p1a: Gliscor|297/353 tox|[from] ability: Poison Heal -|turn|330 -|chat|Pwnemon|:X -| -|switch|p1a: Venusaur|Venusaur, M|344/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -|switch|p2a: Gyarados|Gyarados, F|311/394 slp -|-damage|p2a: Gyarados|213/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Venusaur -|-unboost|p1a: Venusaur|atk|1 -| -|-heal|p2a: Gyarados|237/394 slp|[from] item: Leftovers -|turn|331 -| -|cant|p2a: Gyarados|slp -|move|p1a: Venusaur|Giga Drain|p2a: Gyarados -|-damage|p2a: Gyarados|125/394 slp -|-heal|p1a: Venusaur|364/364|[from] drain|[of] p2a: Gyarados -| -|-heal|p2a: Gyarados|149/394 slp|[from] item: Leftovers -|turn|332 -| -|cant|p2a: Gyarados|slp -|move|p1a: Venusaur|Giga Drain|p2a: Gyarados -|-damage|p2a: Gyarados|50/394 slp -| -|-heal|p2a: Gyarados|74/394 slp|[from] item: Leftovers -|turn|333 -|chat|PKLaurel|crit -|chat|Arcticblast|Has Venusaur revealed its last move? -| -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Venusaur|Giga Drain|p2a: Gyarados -|-damage|p2a: Gyarados|289/394 slp -| -|-heal|p2a: Gyarados|313/394 slp|[from] item: Leftovers -|turn|334 -|chat|chieliee|synth giga eq -|chat|Sir|could it be curse venu -| -|switch|p2a: Blissey|Blissey, F|571/688 -|-damage|p2a: Blissey|485/688|[from] Stealth Rock -|switch|p1a: Skarmory|Skarmory, F|306/334 -| -|-heal|p1a: Skarmory|326/334|[from] item: Leftovers -|-heal|p2a: Blissey|528/688|[from] item: Leftovers -|turn|335 -|chat|Texas Cloverleaf|it revealed sludge -| -|move|p1a: Skarmory|Brave Bird|p2a: Blissey -|-damage|p2a: Blissey|311/688 -|-damage|p1a: Skarmory|254/334|[from] recoil|[of] p2a: Blissey -|move|p2a: Blissey|Seismic Toss|p1a: Skarmory -|-damage|p1a: Skarmory|154/334 -| -|-heal|p1a: Skarmory|174/334|[from] item: Leftovers -|-heal|p2a: Blissey|354/688|[from] item: Leftovers -|turn|336 -|chat|Arcticblast|Oh it did? -|chat|OU Mew|yeah 200 turns ago -| -|move|p1a: Skarmory|Roost|p1a: Skarmory -|-heal|p1a: Skarmory|334/334 -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-heal|p2a: Blissey|688/688 -| -|turn|337 -| -|switch|p1a: Chansey|Chansey, F|485/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|385/660 -| -|turn|338 -|chat|chieliee|yeh -|chat|chieliee|it did -|chat|Soulgazer|I WON -|chat|Soulgazer|go eleyis -|chat|Soulgazer|*-* -| -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -|move|p1a: Chansey|Soft-Boiled|p1a: Chansey -|-heal|p1a: Chansey|660/660 tox -| -|-damage|p1a: Chansey|619/660 tox|[from] psn -|turn|339 -|chat|OU Mew|ou already finished? -|chat|Pwnemon|lol i quit on like turn 3 -|chat|Pwnemon|wasnt really playin ykno -| -|switch|p2a: Gyarados|Gyarados, F|313/394 slp -|-damage|p2a: Gyarados|215/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Chansey -|-unboost|p1a: Chansey|atk|1 -|switch|p1a: Gliscor|Gliscor, M|297/353 tox -| -|-heal|p2a: Gyarados|239/394 slp|[from] item: Leftovers -|-heal|p1a: Gliscor|341/353 tox|[from] ability: Poison Heal -|turn|340 -|chat|chieliee|excuses -|chat|Soulgazer|you just got wreck -|chat|Pwnemon|ya -|chat|Soulgazer|start me in doubles nachos -|chat|Pwnemon|ok -|chat|Soulgazer|im rdy -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|cant|p2a: Gyarados|slp -| -|-heal|p2a: Gyarados|263/394 slp|[from] item: Leftovers -|turn|341 -|chat|Pwnemon|eh ud do better than yung -|chat|Stone_Cold22|yung is fine -|chat|Delta 2777|doesn't XY have a 1-hour time limit -|chat|Stone_Cold22|hop off faggot -| -|switch|p1a: Quagsire|Quagsire, M|348/393 -|cant|p2a: Gyarados|slp -| -|-heal|p2a: Gyarados|287/394 slp|[from] item: Leftovers -|-heal|p1a: Quagsire|372/393|[from] item: Leftovers -|turn|342 -|chat|Pwnemon|only in battle spot delta -|chat|Soulgazer|ya yung is great -| -|switch|p1a: Skarmory|Skarmory, F|334/334 -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p2a: Gyarados|311/394|[from] item: Leftovers -|turn|343 -|chat|chieliee|fuck this shit im out -|chat|Nachos|so many people mad at yungjake :( -|chat|Stone_Cold22|ur jsut not based enought o keep up w/ yung -| -|move|p2a: Gyarados|Waterfall|p1a: Skarmory -|-damage|p1a: Skarmory|240/334 -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Clefable|Clefable, M|243/394 -|-damage|p2a: Clefable|194/394|[from] Stealth Rock -| -|-heal|p1a: Skarmory|260/334|[from] item: Leftovers -|-heal|p2a: Clefable|218/394|[from] item: Leftovers -|turn|344 -|chat|Ginku|why would anyone be mad at yungjake -|chat|Nachos|idk -|chat|OU Mew|in-game battles of 400+ turns unlock Volcanion -| -|switch|p1a: Heatran|Heatran, M|361/385 -|move|p2a: Clefable|Wish|p2a: Clefable -| -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|-heal|p2a: Clefable|242/394|[from] item: Leftovers -|turn|345 -|chat|Pwnemon|lol -|chat|Afro Smash|cuz theyre not as good as him -|chat|Pwnemon|ya thats it -|chat|MikeDecIsHere|ye -|chat|Pwnemon|lol -|chat|Soulgazer|so yung,, -|chat|Sapientia|why are there 2 mons dead if lb can stall for 100+ turns with the other 4 :hm: -|chat|Stone_Cold22|pwnemon -|chat|Laga|he disagreed with pwnemon on a subject yesterday -|chat|Stone_Cold22|when have you ever been relevent? -| -|move|p2a: Clefable|Protect|p2a: Clefable -|-singleturn|p2a: Clefable|Protect -|move|p1a: Heatran|Roar|p2a: Clefable -|drag|p2a: Gyarados|Gyarados, F|311/394 -|-damage|p2a: Gyarados|213/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -| -|-heal|p2a: Gyarados|394/394|[from] move: Wish|[wisher] Clefable -|turn|346 -|chat|Stone_Cold22|im trying to recall -|chat|Stone_Cold22|:/ -|chat|Laga|that is why he hates him -|chat|MarceloDK|wtf -|chat|MikeDecIsHere|Stone -|chat|Soulgazer|lol -|chat|MikeDecIsHere|only for worst forum poster -|chat|Stone_Cold22|going hard -|chat|McMeghan|can you even legitimatly play 1 hour+ game on catridge? :O -|chat|MikeDecIsHere|that's about it -|chat|PKLaurel|Shots fired -|chat|Stone_Cold22|oh -| -|switch|p1a: Quagsire|Quagsire, M|372/393 -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|turn|347 -|chat|MarceloDK|did this roar just go through protect -|chat|PKLaurel|No you cant McMeghan -|chat|Stone_Cold22|mike thats where i recognized da name -|chat|Pwnemon|ow my heart -|chat|MarceloDK|?___? -|chat|Eo|yes marcy... -|chat|Soulgazer|marcy -|chat|PKLaurel|It ties -|chat|Pwnemon|dam -|chat|Afro Smash|wepwnpokemon > pwnemon -|chat|Soulgazer|new mechanics -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-crit|p1a: Quagsire -|-damage|p1a: Quagsire|255/393 -|move|p1a: Quagsire|Toxic|p2a: Gyarados -|-status|p2a: Gyarados|tox -| -|-heal|p1a: Quagsire|279/393|[from] item: Leftovers -|-damage|p2a: Gyarados|370/394 tox|[from] psn -|turn|348 -|chat|Eo|this is why you are playing adv -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|195/393 -|move|p1a: Quagsire|Recover|p1a: Quagsire -|-heal|p1a: Quagsire|392/393 -| -|-heal|p2a: Gyarados|394/394 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|393/393|[from] item: Leftovers -|-damage|p2a: Gyarados|346/394 tox|[from] psn -|turn|349 -|chat|Stone_Cold22|eo ut mortus -|chat|Stone_Cold22|big fan -| -|switch|p1a: Venusaur|Venusaur, M|364/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Gyarados|Earthquake|p1a: Venusaur -|-damage|p1a: Venusaur|237/364 -| -|-heal|p2a: Gyarados|370/394 tox|[from] item: Leftovers -|-damage|p2a: Gyarados|298/394 tox|[from] psn -|turn|350 -|chat|PttP|0-2 duo of mareclo and eo -|chat|PttP|carry team -|chat|Soulgazer|now that hurts -| -|switch|p1a: Skarmory|Skarmory, F|260/334 -|move|p2a: Gyarados|Earthquake|p1a: Skarmory -|-immune|p1a: Skarmory|[msg] -| -|-heal|p2a: Gyarados|322/394 tox|[from] item: Leftovers -|-heal|p1a: Skarmory|280/334|[from] item: Leftovers -|-damage|p2a: Gyarados|226/394 tox|[from] psn -|turn|351 -|chat|dekzeh|:] -|chat|PKLaurel|is blisseys last aroma? -|chat|Eo|:] -|chat|Annoyer|y -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -| -|turn|352 -|chat|Pwnemon|no aroma here -|chat|MarceloDK|I'm 0-2 to support Eo -|chat|Pwnemon|lol -| -|switch|p1a: Skarmory|Skarmory, F|280/334 -|cant|p2a: Gyarados|slp -| -|-heal|p1a: Skarmory|300/334|[from] item: Leftovers -|turn|353 -|chat|Sapientia|marcelo just wins in play offs -|chat|Sapientia|fuck the rest -|chat|MarceloDK|otherwise we would be the only one that sucks -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Clefable|Clefable, M|242/394 -|-damage|p2a: Clefable|193/394|[from] Stealth Rock -| -|-heal|p1a: Skarmory|320/334|[from] item: Leftovers -|-heal|p2a: Clefable|217/394|[from] item: Leftovers -|turn|354 -|chat|MarceloDK|on the team -|chat|Sapientia|just like he starts playing tour in play offs -|chat|MarceloDK|o_o -|chat|Afro Smash|reveal the taunt -| -|move|p1a: Skarmory|Brave Bird|p2a: Clefable -|-damage|p2a: Clefable|123/394 -|-damage|p1a: Skarmory|289/334|[from] recoil|[of] p2a: Clefable -|move|p2a: Clefable|Wish|p2a: Clefable -| -|-heal|p1a: Skarmory|309/334|[from] item: Leftovers -|-heal|p2a: Clefable|147/394|[from] item: Leftovers -|turn|355 -|chat|Pwnemon|lol -| -|switch|p1a: Heatran|Heatran, M|385/385 -|move|p2a: Clefable|Moonblast|p1a: Heatran -|-resisted|p1a: Heatran -|-damage|p1a: Heatran|367/385 -| -|-heal|p2a: Clefable|344/394|[from] move: Wish|[wisher] Clefable -|-heal|p1a: Heatran|385/385|[from] item: Leftovers -|-heal|p2a: Clefable|368/394|[from] item: Leftovers -|turn|356 -|chat|Pwnemon|aw cm if real -|chat|Soulgazer|nice damage -|chat|OU Mew|normal gem hyper beam pls -|chat|Pwnemon|lol -|chat|Stone_Cold22|not real -| -|move|p2a: Clefable|Protect|p2a: Clefable -|-singleturn|p2a: Clefable|Protect -|move|p1a: Heatran|Lava Plume|p2a: Clefable -|-activate|p2a: Clefable|Protect -| -|-heal|p2a: Clefable|392/394|[from] item: Leftovers -|turn|357 -| -|switch|p2a: Gyarados|Gyarados, F|394/394 slp -|-damage|p2a: Gyarados|296/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Heatran -|-unboost|p1a: Heatran|atk|1 -|move|p1a: Heatran|Lava Plume|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|242/394 slp -| -|-heal|p2a: Gyarados|266/394 slp|[from] item: Leftovers -|turn|358 -| -|switch|p1a: Quagsire|Quagsire, M|393/393 -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Earthquake|p1a: Quagsire -|-damage|p1a: Quagsire|314/393 -| -|-heal|p2a: Gyarados|290/394|[from] item: Leftovers -|-heal|p1a: Quagsire|338/393|[from] item: Leftovers -|turn|359 -|chat|Mr.E|WHY IS THIS GAME SO LONG -|chat|Pwnemon|lol -|chat|Pwnemon|when a gscer says it -|chat|MikeDecIsHere|don't you play GSC? -|chat|Pwnemon|u know its ridiculous -| -|switch|p2a: Blissey|Blissey, F|688/688 -|-damage|p2a: Blissey|602/688|[from] Stealth Rock -|move|p1a: Quagsire|Scald|p2a: Blissey -|-damage|p2a: Blissey|556/688 -| -|-heal|p2a: Blissey|599/688|[from] item: Leftovers -|-heal|p1a: Quagsire|362/393|[from] item: Leftovers -|turn|360 -|chat|Soulgazer|where's the burn -|chat|Soulgazer|:( -| -|switch|p1a: Gliscor|Gliscor, M|341/353 tox -|move|p2a: Blissey|Toxic|p1a: Gliscor -|-fail|p1a: Gliscor|tox -| -|-heal|p2a: Blissey|642/688|[from] item: Leftovers -|-heal|p1a: Gliscor|353/353 tox|[from] ability: Poison Heal -|turn|361 -|chat|Aqualouis|o -|chat|Aqualouis|this is not over -|chat|Mr.E|chansey v blissey -| -|move|p1a: Gliscor|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -|move|p2a: Blissey|Seismic Toss|p1a: Gliscor -|-damage|p1a: Gliscor|253/353 tox -| -|-heal|p2a: Blissey|685/688 tox|[from] item: Leftovers -|-heal|p1a: Gliscor|297/353 tox|[from] ability: Poison Heal -|-damage|p2a: Blissey|642/688 tox|[from] psn -|turn|362 -|chat|Sir|last mon gyarados wins -|chat|Sir|i reckon -|chat|Sir|could go either way -| -|switch|p2a: Clefable|Clefable, M|392/394 -|-damage|p2a: Clefable|343/394|[from] Stealth Rock -|move|p1a: Gliscor|Earthquake|p2a: Clefable -|-damage|p2a: Clefable|238/394 -| -|-heal|p2a: Clefable|262/394|[from] item: Leftovers -|-heal|p1a: Gliscor|341/353 tox|[from] ability: Poison Heal -|turn|363 -|chat|PKLaurel|it depends -| -|move|p2a: Clefable|Protect|p2a: Clefable -|-singleturn|p2a: Clefable|Protect -|move|p1a: Gliscor|Toxic|p2a: Clefable -|-activate|p2a: Clefable|Protect -| -|-heal|p2a: Clefable|286/394|[from] item: Leftovers -|-heal|p1a: Gliscor|353/353 tox|[from] ability: Poison Heal -|turn|364 -| -|move|p1a: Gliscor|Toxic|p2a: Clefable -|-status|p2a: Clefable|tox -|move|p2a: Clefable|Calm Mind|p2a: Clefable -|-boost|p2a: Clefable|spa|1 -|-boost|p2a: Clefable|spd|1 -| -|-heal|p2a: Clefable|310/394 tox|[from] item: Leftovers -|-damage|p2a: Clefable|286/394 tox|[from] psn -|turn|365 -|chat|PKLaurel|i think quag beats it if it has more recovers than gyara rests -| -|switch|p1a: Heatran|Heatran, M|385/385 -|switch|p2a: Blissey|Blissey, F|642/688 -|-damage|p2a: Blissey|556/688|[from] Stealth Rock -| -|-heal|p2a: Blissey|599/688|[from] item: Leftovers -|turn|366 -| -|move|p2a: Blissey|Seismic Toss|p1a: Heatran -|-damage|p1a: Heatran|285/385 -|move|p1a: Heatran|Roar|p2a: Blissey -|drag|p2a: Clefable|Clefable, M|286/394 tox -|-damage|p2a: Clefable|237/394 tox|[from] Stealth Rock -| -|-heal|p1a: Heatran|309/385|[from] item: Leftovers -|-heal|p2a: Clefable|261/394 tox|[from] item: Leftovers -|-damage|p2a: Clefable|237/394 tox|[from] psn -|turn|367 -|chat|Mr.E|if this was GSC -|chat|Mr.E|this heatran would have explosion -|chat|Pwnemon|lol -| -|move|p1a: Heatran|Lava Plume|p2a: Clefable -|-damage|p2a: Clefable|113/394 tox -|move|p2a: Clefable|Wish|p2a: Clefable -| -|-heal|p1a: Heatran|333/385|[from] item: Leftovers -|-heal|p2a: Clefable|137/394 tox|[from] item: Leftovers -|-damage|p2a: Clefable|89/394 tox|[from] psn -|turn|368 -|chat|Pwnemon|or dpp -|chat|Sir|n -|chat|george182|if this was gac -|chat|MarceloDK|ugh -| -|move|p2a: Clefable|Protect|p2a: Clefable -|-singleturn|p2a: Clefable|Protect -|move|p1a: Heatran|Roar|p2a: Clefable -|drag|p2a: Blissey|Blissey, F|599/688 -|-damage|p2a: Blissey|513/688|[from] Stealth Rock -| -|-heal|p2a: Blissey|688/688|[from] move: Wish|[wisher] Clefable -|-heal|p1a: Heatran|357/385|[from] item: Leftovers -|turn|369 -|chat|george182|thered be no heatran -|chat|MarceloDK|death -|chat|Pwnemon|oh shit -|chat|MarceloDK|nice shitass new mecanics -|chat|MarceloDK|:( -| -|switch|p1a: Chansey|Chansey, F|619/660 -|move|p2a: Blissey|Seismic Toss|p1a: Chansey -|-damage|p1a: Chansey|519/660 -| -|turn|370 -|chat|Mr.E|awesome new mechanics* -| -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -|move|p1a: Chansey|Seismic Toss|p2a: Blissey -|-damage|p2a: Blissey|588/688 -| -|-heal|p2a: Blissey|631/688|[from] item: Leftovers -|-damage|p1a: Chansey|478/660 tox|[from] psn -|turn|371 -| -|switch|p2a: Gyarados|Gyarados, F|290/394 -|-damage|p2a: Gyarados|192/394|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Chansey -|-unboost|p1a: Chansey|atk|1 -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -| -|-heal|p2a: Gyarados|216/394|[from] item: Leftovers -|turn|372 -|chat|Mr.E|literally chansey and blissey -|chat|Afro Smash|the damage -|chat|Mr.E|fucking seismic tossing each other -|chat|MarceloDK|mr.e always uses machamp -|chat|MarceloDK|yn -|chat|Pwnemon|lol -| -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -|move|p1a: Venusaur|Sludge Bomb|p2a: Gyarados -|-damage|p2a: Gyarados|98/394 -|-status|p2a: Gyarados|psn -| -|-heal|p2a: Gyarados|122/394 psn|[from] item: Leftovers -|-damage|p2a: Gyarados|73/394 psn|[from] psn -|turn|373 -|chat|Pwnemon|rest time -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Venusaur|Sludge Bomb|p2a: Gyarados -|-damage|p2a: Gyarados|265/394 slp -| -|-heal|p2a: Gyarados|289/394 slp|[from] item: Leftovers -|turn|374 -|chat|PKLaurel|crit once -|chat|Soulgazer|can i see -|chat|Soulgazer|a crit sludge -| -|switch|p2a: Blissey|Blissey, F|631/688 -|-damage|p2a: Blissey|545/688|[from] Stealth Rock -|switch|p1a: Skarmory|Skarmory, F|309/334 -| -|-heal|p1a: Skarmory|329/334|[from] item: Leftovers -|-heal|p2a: Blissey|588/688|[from] item: Leftovers -|turn|375 -|chat|Soulgazer|:] -|chat|Mr.E|needs more leech seed -|chat|Mr.E|both these teams even have skarmory -|chat|Mr.E|fuck -|chat|Pwnemon|stall whitout skarm -| -|switch|p1a: Gliscor|Gliscor, M|353/353 tox -|move|p2a: Blissey|Seismic Toss|p1a: Gliscor -|-damage|p1a: Gliscor|253/353 tox -| -|-heal|p2a: Blissey|631/688|[from] item: Leftovers -|-heal|p1a: Gliscor|297/353 tox|[from] ability: Poison Heal -|turn|376 -|chat|Pwnemon|isnt a thing -|chat|Pwnemon|ever -|chat|PKLaurel|yes it is -|chat|Pwnemon|lol -|chat|PKLaurel|theres a bird called mandibuzz -| -|switch|p2a: Gyarados|Gyarados, F|289/394 slp -|-damage|p2a: Gyarados|191/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Gliscor -|-unboost|p1a: Gliscor|atk|1 -|move|p1a: Gliscor|Protect|p1a: Gliscor -|-fail|p1a: Gliscor -| -|-heal|p2a: Gyarados|215/394 slp|[from] item: Leftovers -|-heal|p1a: Gliscor|341/353 tox|[from] ability: Poison Heal -|turn|377 -|chat|Pwnemon|right -| -|switch|p1a: Skarmory|Skarmory, F|329/334 -|cant|p2a: Gyarados|slp -| -|-heal|p2a: Gyarados|239/394 slp|[from] item: Leftovers -|-heal|p1a: Skarmory|334/334|[from] item: Leftovers -|turn|378 -|chat|PKLaurel|eq -|chat|OU Mew|Gourgeist would have rekt here -| -|cant|p2a: Gyarados|slp -|move|p1a: Skarmory|Whirlwind|p2a: Gyarados -|drag|p2a: Nidoqueen|Nidoqueen, F|156/384 -|-damage|p2a: Nidoqueen|132/384|[from] Stealth Rock -| -|-heal|p2a: Nidoqueen|156/384|[from] item: Leftovers -|turn|379 -|chat|Mr.E|gourgeist is unstoppable -|chat|Arcticblast|Taunt DD Gyarados would have ended this turn 60 -| -|switch|p1a: Gliscor|Gliscor, M|341/353 tox -|move|p2a: Nidoqueen|Flamethrower|p1a: Gliscor -|-damage|p1a: Gliscor|243/353 tox -| -|-heal|p2a: Nidoqueen|180/384|[from] item: Leftovers -|-heal|p1a: Gliscor|287/353 tox|[from] ability: Poison Heal -|turn|380 -|chat|boudouche|ROFL -|chat|boudouche|WTF -|chat|Stone_Cold22|articblast -|chat|Stone_Cold22|quagsire scald? -|chat|boudouche|379 turns ? x.x -|chat|MikeDecIsHere|Quag -|chat|MikeDecIsHere|moron -|chat|MikeDecIsHere|:| -|chat|Pwnemon|lol -|chat|Stone_Cold22|fucking idiot -|chat|Soulgazer|oui boud -|chat|Snunch|basically anything with taunt would have ended the game a long time ago -|chat|Soulgazer|Oo -|chat|PttP|moron -| -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|switch|p2a: Gyarados|Gyarados, F|239/394 slp -|-damage|p2a: Gyarados|141/394 slp|[from] Stealth Rock -|-ability|p2a: Gyarados|Intimidate|[of] p1a: Venusaur -|-unboost|p1a: Venusaur|atk|1 -| -|-heal|p2a: Gyarados|165/394 slp|[from] item: Leftovers -|turn|381 -|chat|Stone_Cold22|oui oui -|chat|MikeDecIsHere|ily still though -|chat|MarceloDK|its taunt dd subs -|chat|Annoyer|mega gyara would have -|chat|MarceloDK|you FOOLS -|chat|Mr.E|anything with explosion would've ended the game a long time ago -| -|switch|p2a: Blissey|Blissey, F|631/688 -|-damage|p2a: Blissey|545/688|[from] Stealth Rock -|move|p1a: Venusaur|Sludge Bomb|p2a: Blissey -|-damage|p2a: Blissey|448/688 -|-status|p2a: Blissey|psn -| -|-heal|p2a: Blissey|491/688 psn|[from] item: Leftovers -|-damage|p2a: Blissey|405/688 psn|[from] psn -|turn|382 -|chat|Soulgazer|marcy,, -|chat|Afro Smash|the crit -|chat|DTC|oh shit -|chat|THE_IRON_KENYAN|hon hon hon -|chat|Pwnemon|the psn -| -|switch|p1a: Chansey|Chansey, F|478/660 -|move|p2a: Blissey|Aromatherapy|p2a: Blissey -|-cureteam|p2a: Blissey|[from] move: Aromatherapy -| -|-heal|p2a: Blissey|448/688|[from] item: Leftovers -|turn|383 -|chat|Afro Smash|got him on the ropes!! -|chat|PttP|intense -|chat|Soulgazer|omelette du fromage -|chat|Pwnemon|last aroma? -| -|move|p2a: Blissey|Toxic|p1a: Chansey|[miss] -|-miss|p2a: Blissey|p1a: Chansey -|move|p1a: Chansey|Seismic Toss|p2a: Blissey -|-damage|p2a: Blissey|348/688 -| -|-heal|p2a: Blissey|391/688|[from] item: Leftovers -|turn|384 -|chat|Stone_Cold22|could this be -|chat|Stone_Cold22|the longest 6-0 ever? -| -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Blissey|Toxic|p1a: Venusaur -|-fail|p1a: Venusaur -| -|-heal|p2a: Blissey|434/688|[from] item: Leftovers -|turn|385 -|chat|Pwnemon|lol -| -|switch|p1a: Chansey|Chansey, F|478/660 -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-heal|p2a: Blissey|688/688 -| -|turn|386 -| -|move|p2a: Blissey|Toxic|p1a: Chansey -|-status|p1a: Chansey|tox -|move|p1a: Chansey|Toxic|p2a: Blissey -|-status|p2a: Blissey|tox -| -|-damage|p2a: Blissey|645/688 tox|[from] psn -|-damage|p1a: Chansey|437/660 tox|[from] psn -|turn|387 -|chat|Heist|lord elyis would have won 150 turns ago if he wasn't playing for the 6-0 #shameful -| -|switch|p2a: Clefable|Clefable, M|89/394 -|-damage|p2a: Clefable|40/394|[from] Stealth Rock -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -| -|-heal|p2a: Clefable|64/394|[from] item: Leftovers -|turn|388 -| -|move|p2a: Clefable|Protect|p2a: Clefable -|-singleturn|p2a: Clefable|Protect -|move|p1a: Venusaur|Giga Drain|p2a: Clefable -|-activate|p2a: Clefable|Protect -| -|-heal|p2a: Clefable|88/394|[from] item: Leftovers -|turn|389 -|chat|Afro Smash|:] -|chat|Soulgazer|nicee -|chat|Pwnemon|lol -|chat|Soulgazer|:] -|chat|MarceloDK|how, kev? -|chat|MarceloDK|o.o -| -|move|p2a: Clefable|Protect|p2a: Clefable -|-fail|p2a: Clefable -|move|p1a: Venusaur|Sludge Bomb|p2a: Clefable -|-supereffective|p2a: Clefable -|-damage|p2a: Clefable|0 fnt -|faint|p2a: Clefable -| -|chat|Pwnemon|ooooooooo -|chat|Annoyer|6-3. -|chat|Stone_Cold22|xDDD -|chat|jumpluff|rip -|chat|Arcticblast|THIRD KILL -| -|switch|p2a: Blissey|Blissey, F|645/688 -|-damage|p2a: Blissey|559/688|[from] Stealth Rock -|turn|390 -|chat|Soulgazer|THIRD BLOOD -|chat|Afro Smash|king fuckin elyis -|chat|Pwnemon|game -| -|switch|p1a: Chansey|Chansey, F|437/660 -|switch|p2a: Nidoqueen|Nidoqueen, F|180/384 -|-damage|p2a: Nidoqueen|156/384|[from] Stealth Rock -| -|-heal|p2a: Nidoqueen|180/384|[from] item: Leftovers -|turn|391 -|chat|Pwnemon|over -|chat|the pdc show|300 is for 3 -| -|move|p2a: Nidoqueen|Toxic Spikes|p1a: Chansey -|-sidestart|p1: Lord Elyis|move: Toxic Spikes -|move|p1a: Chansey|Seismic Toss|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|80/384 -| -|-heal|p2a: Nidoqueen|104/384|[from] item: Leftovers -|turn|392 -|chat|Annoyer|n 389 for 3 -|chat|Texas Cloverleaf|elyis doesnt win without some very fortunate roar/ww rolls tho -|chat|Soulgazer|pdc -|chat|Soulgazer|do u mean -|chat|Annoyer|778 for 6 -| -|switch|p2a: Blissey|Blissey, F|559/688 -|-damage|p2a: Blissey|473/688|[from] Stealth Rock -|move|p1a: Chansey|Seismic Toss|p2a: Blissey -|-damage|p2a: Blissey|373/688 -| -|-heal|p2a: Blissey|416/688|[from] item: Leftovers -|turn|393 -|chat|Soulgazer|turn 400 is for 4th kill -|chat|Soulgazer|?! -|chat|the pdc show|yes -| -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-sideend|p1: Lord Elyis|move: Toxic Spikes|[of] p1a: Venusaur -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-heal|p2a: Blissey|688/688 -| -|turn|394 -|chat|the pdc show|it is prophesised -| -|switch|p1a: Chansey|Chansey, F|437/660 -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-fail|p2a: Blissey -| -|turn|395 -|chat|OU Mew|2 kills within 100 turns insaaannee -|chat|the pdc show|prophesied -| -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-fail|p2a: Blissey -| -|turn|396 -| -|switch|p1a: Chansey|Chansey, F|437/660 -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-fail|p2a: Blissey -| -|turn|397 -|chat|MarceloDK|._. -| -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-fail|p2a: Blissey -| -|turn|398 -| -|switch|p1a: Chansey|Chansey, F|437/660 -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-fail|p2a: Blissey -| -|turn|399 -|chat|Stone_Cold22|xD -|chat|Mr.E|lady bug you should press the (x) at the top of the page -|chat|MarceloDK|why lady bug just doesn't forfeit -|chat|Mr.E|and save us all a whole lot of trouble -| -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-fail|p2a: Blissey -| -|turn|400 -|chat|Afro Smash|i cant think of anything id rather be doing with my time tbh -|chat|OU Mew|ctrl + Q -|chat|Annoyer|and himself -|chat|Mr.E|fucking picollo 2.0 right here -|chat|MarceloDK|which kind of sick person finds this funny -| -|switch|p1a: Chansey|Chansey, F|437/660 -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-fail|p2a: Blissey -| -|turn|401 -|chat|MarceloDK|o.o -|chat|Pwnemon|le thug -|chat|LonelyNess|last mon gyara has the opportunity to crit flinch to victory -|chat|LonelyNess|so might as well take the chance -| -|switch|p2a: Nidoqueen|Nidoqueen, F|104/384 -|-damage|p2a: Nidoqueen|80/384|[from] Stealth Rock -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -| -|-heal|p2a: Nidoqueen|104/384|[from] item: Leftovers -|turn|402 -|chat|PttP|7 fnliches in a row -|chat|Hot N Cold|venusaur sludge bomb?? -|chat|MarceloDK|its needs 3 crit flinches -|chat|Annoyer|he only has like 7 waterfalls left -|chat|MarceloDK|LN -| -|switch|p2a: Blissey|Blissey, F|688/688 -|-damage|p2a: Blissey|602/688|[from] Stealth Rock -|move|p1a: Venusaur|Earthquake|p2a: Blissey -|-damage|p2a: Blissey|465/688 -| -|-heal|p2a: Blissey|508/688|[from] item: Leftovers -|turn|403 -|chat|Mr.E|if gyarados can even kill everything before running out of PP I'd be impressed -|chat|Annoyer|or some small number like that -|chat|MarceloDK|crit is only 1.5 now -| -|switch|p1a: Chansey|Chansey, F|437/660 -|move|p2a: Blissey|Soft-Boiled|p2a: Blissey -|-heal|p2a: Blissey|688/688 -| -|turn|404 -|chat|LonelyNess|MarceloDK, that is a non-zero chance to win -|chat|Mr.E|RIP -|chat|Hot N Cold|venusaur sludge bomb + no PP's lol -|chat|LonelyNess|might as well take it -|chat|Mr.E|Turn 404 -| -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|move|p2a: Blissey|Aromatherapy|p2a: Blissey -|-cureteam|p2a: Blissey|[from] move: Aromatherapy -| -|turn|405 -| -|switch|p1a: Chansey|Chansey, F|437/660 -|move|p2a: Blissey|Aromatherapy|p2a: Blissey -|-cureteam|p2a: Blissey|[from] move: Aromatherapy -| -|turn|406 -|chat|Mr.E|pokemon battle not found -| -|switch|p1a: Venusaur|Venusaur, M|237/364 -|-formechange|p1a: Venusaur|Venusaur-Mega -|-activate|p2a: Blissey|move: Struggle -|move|p2a: Blissey|Struggle|p1a: Venusaur -|-damage|p1a: Venusaur|229/364 -|-damage|p2a: Blissey|516/688 -| -|-heal|p2a: Blissey|559/688|[from] item: Leftovers -|turn|407 -|chat|jumpluff|! -|chat|Afro Smash|the struggle is real -| -|switch|p1a: Gliscor|Gliscor, M|287/353 tox -|-activate|p2a: Blissey|move: Struggle -|move|p2a: Blissey|Struggle|p1a: Gliscor -|-damage|p1a: Gliscor|282/353 tox -|-damage|p2a: Blissey|387/688 -| -|-heal|p2a: Blissey|430/688|[from] item: Leftovers -|-heal|p1a: Gliscor|326/353 tox|[from] ability: Poison Heal -|turn|408 -|chat|PttP|ooh kill em -|chat|jumpluff|lmao -|chat|Annoyer|damn -|chat|OU Mew|most damage on blissey whole game -|chat|Soulgazer|:] -| -|move|p1a: Gliscor|Substitute|p1a: Gliscor -|-start|p1a: Gliscor|Substitute -|-damage|p1a: Gliscor|238/353 tox -|-activate|p2a: Blissey|move: Struggle -|move|p2a: Blissey|Struggle|p1a: Gliscor -|-activate|p1a: Gliscor|Substitute|[damage] -|-damage|p2a: Blissey|258/688 -| -|-heal|p2a: Blissey|301/688|[from] item: Leftovers -|-heal|p1a: Gliscor|282/353 tox|[from] ability: Poison Heal -|turn|409 -| -|move|p1a: Gliscor|Earthquake|p2a: Blissey -|-damage|p2a: Blissey|93/688 -|-activate|p2a: Blissey|move: Struggle -|move|p2a: Blissey|Struggle|p1a: Gliscor -|-activate|p1a: Gliscor|Substitute|[damage] -|-damage|p2a: Blissey|0 fnt -|faint|p2a: Blissey -| -|-heal|p1a: Gliscor|326/353 tox|[from] ability: Poison Heal -|chat|Sir|imagine ladybug wins -|chat|Pwnemon|lol -|chat|Afro Smash|no -|chat|Mr.E|spoilers: lady bug loses -| -|switch|p2a: Nidoqueen|Nidoqueen, F|104/384 -|-damage|p2a: Nidoqueen|80/384|[from] Stealth Rock -|turn|410 -|chat|Ginku|yea -|chat|Ginku|imagine. -|chat|Mr.E|hey that's a real tag wtf -|chat|Annoyer|woah how do you do that -| -|move|p1a: Gliscor|Earthquake|p2a: Nidoqueen -|-supereffective|p2a: Nidoqueen -|-damage|p2a: Nidoqueen|0 fnt -|faint|p2a: Nidoqueen -| -|-heal|p1a: Gliscor|353/353 tox|[from] ability: Poison Heal -|chat|Treecko|lol -|chat|jdarden|lol yeah -|chat|Annoyer|spoilers: =) -|chat|Soulgazer|ah not bad -| -|switch|p2a: Gyarados|Gyarados, F|165/394 -|-damage|p2a: Gyarados|67/394|[from] Stealth Rock -|-activate|p1a: Gliscor|Substitute|ability: Intimidate|[of] p2a: Gyarados -|turn|411 -|chat|MikeDecIsHere|Spoilers: spoilers does that -|chat|Treecko|it's just "spoilers: text" -|chat|Treecko|oh -|chat|Treecko|oops -|chat|Soulgazer|spoilers: paco -| -|move|p1a: Gliscor|Toxic|p2a: Gyarados -|-status|p2a: Gyarados|tox -|move|p2a: Gyarados|Dragon Dance|p2a: Gyarados -|-boost|p2a: Gyarados|atk|1 -|-boost|p2a: Gyarados|spe|1 -| -|-heal|p2a: Gyarados|91/394 tox|[from] item: Leftovers -|-damage|p2a: Gyarados|67/394 tox|[from] psn -|turn|412 -|chat|PttP|spoilers: eo is a faggot -|chat|Mr.E|spoilers: spoilers: spoilers: -|chat|Blue Eon|:a: -|chat|PttP|well i guess it wasnt that secret -|chat|Blue Eon|fuck tha -|chat|Blue Eon|t -|chat|Annoyer|new spectator secret. -|chat|Pwnemon|lol -|chat|Texas Cloverleaf|spoilers: test -| -|switch|p1a: Quagsire|Quagsire, M|362/393 -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|263/393 -| -|-heal|p2a: Gyarados|91/394 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|287/393|[from] item: Leftovers -|-damage|p2a: Gyarados|43/394 tox|[from] psn -|turn|413 -|chat|MikeDecIsHere|Texas -|chat|MikeDecIsHere|youre a PS mod -|chat|Pwnemon|spoiler: game over -|chat|Arcticblast|test in lobby :| -|chat|MikeDecIsHere|and you didn't know that? -|chat|MikeDecIsHere|lol -|chat|jdarden|see this is why we took it away from ps -|chat|Soulgazer|Mr. Quag -|chat|Texas Cloverleaf|i knew it -| -|move|p2a: Gyarados|Rest|p2a: Gyarados -|-status|p2a: Gyarados|slp -|-heal|p2a: Gyarados|394/394 slp|[silent] -|-status|p2a: Gyarados|slp|[from] move: Rest -|move|p1a: Quagsire|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p1a: Quagsire|311/393|[from] item: Leftovers -|turn|414 -|chat|Texas Cloverleaf|i just never remembered the syntax -|chat|Arcticblast|LAST REST OF THE GAME -|chat|OU Mew|spoiler: d'oh -| -|cant|p2a: Gyarados|slp -|move|p1a: Quagsire|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p1a: Quagsire|335/393|[from] item: Leftovers -|turn|415 -|chat|Afro Smash|spoiler: free sinclair -|chat|Sir|articblast -|chat|Sir|did u account for pp max -| -|cant|p2a: Gyarados|slp -|move|p1a: Quagsire|Earthquake|p2a: Gyarados -|-immune|p2a: Gyarados|[msg] -| -|-heal|p1a: Quagsire|359/393|[from] item: Leftovers -|turn|416 -|chat|Arcticblast|yes -| -|-curestatus|p2a: Gyarados|slp -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|274/393 -|move|p1a: Quagsire|Toxic|p2a: Gyarados -|-status|p2a: Gyarados|tox -| -|-heal|p1a: Quagsire|298/393|[from] item: Leftovers -|-damage|p2a: Gyarados|370/394 tox|[from] psn -|turn|417 -|chat|Pwnemon|damn -|chat|Pwnemon|thats big -|chat|Sir|nice -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|210/393 -|move|p1a: Quagsire|Recover|p1a: Quagsire -|-heal|p1a: Quagsire|393/393 -| -|-heal|p2a: Gyarados|394/394 tox|[from] item: Leftovers -|-damage|p2a: Gyarados|346/394 tox|[from] psn -|turn|418 -|chat|Mr.E|FREE SINCLAIR -|chat|Soulgazer|amazing 6-0 -|chat|Stone_Cold22|lady_bro playing it out anywy -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|306/393 -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|313/394 tox -| -|-heal|p2a: Gyarados|337/394 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|330/393|[from] item: Leftovers -|-damage|p2a: Gyarados|265/394 tox|[from] psn -|turn|419 -|chat|Nachos|Free Sinclair. -|chat|Arcticblast|well I think it's the last rest -|chat|Blue Eon|spoiler: gay -|chat|Soulgazer|agreeing with mre -|chat|Arcticblast|idk -|chat|Mr.E|more like lady_bitch -|chat|Soulgazer|free my boy sinclair -|chat|Hot N Cold|spoilers: lmao -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|240/393 -|move|p1a: Quagsire|Recover|p1a: Quagsire -|-heal|p1a: Quagsire|393/393 -| -|-heal|p2a: Gyarados|289/394 tox|[from] item: Leftovers -|-damage|p2a: Gyarados|193/394 tox|[from] psn -|turn|420 -|chat|Mr.E|wasting time -|chat|Mr.E|like a bitch -|chat|Nachos|give sinclair his spl experience :[ -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|293/393 -|move|p1a: Quagsire|Scald|p2a: Gyarados -|-resisted|p2a: Gyarados -|-damage|p2a: Gyarados|163/394 tox -| -|-heal|p2a: Gyarados|187/394 tox|[from] item: Leftovers -|-heal|p1a: Quagsire|317/393|[from] item: Leftovers -|-damage|p2a: Gyarados|67/394 tox|[from] psn -|turn|421 -|chat|Stone_Cold22|spoilers: ggwp -|chat|Lady bug|gg -|chat|Lord Elyis|gg -| -|move|p2a: Gyarados|Waterfall|p1a: Quagsire -|-damage|p1a: Quagsire|221/393 -|move|p1a: Quagsire|Recover|p1a: Quagsire -|-heal|p1a: Quagsire|393/393 -| -|-heal|p2a: Gyarados|91/394 tox|[from] item: Leftovers -|-damage|p2a: Gyarados|0 fnt|[from] psn -|faint|p2a: Gyarados -| -|win|Lord Elyis -|chat|Nachos|gg -|chat|Sir|gg -|chat|Annoyer|almost 420 -|chat|Aqualouis|it's not 6/0 -|chat|Soulgazer|! -|player|p2 -|chat|Aqualouis|it's 6 awww diff --git a/old-replays/search.json.php b/old-replays/search.json.php deleted file mode 100644 index 38124a0a2f..0000000000 --- a/old-replays/search.json.php +++ /dev/null @@ -1,51 +0,0 @@ -userid($username); -$isPrivateAllowed = ($username === $curuser['userid'] || $curuser['userid'] === 'zarel'); -if ($isPrivate && !$isPrivateAllowed) { - die('"ERROR: access denied"'); -} - -$page = intval($_REQUEST['page'] ?? 0); - -$replays = null; -if ($page > 25) { - die('"ERROR: page limit is 25"'); -} else if ($username || $format) { - $replays = $Replays->search([ - "username" => $username, - "username2" => $username2, - "format" => $format, - "byRating" => $byRating, - "isPrivate" => $isPrivate, - "page" => $page - ]); -} else if ($contains) { - $replays = $Replays->fullSearch($contains, $page); -} else { - $replays = $Replays->recent(); -} - -if ($replays) { - foreach ($replays as &$replay) { - if ($replay['password'] ?? null) { - $replay['id'] .= '-' . $replay['password']; - } - unset($replay['password']); - } -} - -echo json_encode($replays); diff --git a/old-replays/search.php b/old-replays/search.php deleted file mode 100644 index ef191053b6..0000000000 --- a/old-replays/search.php +++ /dev/null @@ -1,277 +0,0 @@ -setPageTitle($username."'s replays"); -} else if ($format) { - $panels->setPageTitle($username." replays"); -} else { - $panels->setPageTitle("Search replays"); -} -$panels->setTab('replay'); -$panels->start(); - -$page = 0; -if (@$_REQUEST['page']) $page = intval($_REQUEST['page']); - -if (!$page) { -?> -
    - -

    Search replays

    -
    -

    - - -

    - -
    -

    - - -

    - - -

    Experimental full-text search

    -
    -

    - - -

    - -userid($username); - $isPrivateAllowed = ($username === $curuser['userid'] || $curuser['userid'] === 'zarel'); - - if (!$page) { -?> -

    Search results for ""

    -toID($format); -?> - - - - - - -

    -'; - if ($count === 51) { - echo ''; - } - } -} - -if (!$page) { -?> -
    - -end(); - -?> From 0b8a9bbf3bfc3232f1526b105438e6be6b46fc88 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Wed, 15 Nov 2023 00:46:35 -0700 Subject: [PATCH 556/770] Fix Tourney Bracket panning for touch devices (#2184) Co-authored-by: SirzBenjie --- js/client-chat-tournament.js | 10 +++++----- style/client.css | 5 +++++ style/client2.css | 3 +++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/js/client-chat-tournament.js b/js/client-chat-tournament.js index 56a0e73c62..d7fb169b29 100644 --- a/js/client-chat-tournament.js +++ b/js/client-chat-tournament.js @@ -60,11 +60,11 @@ var innerX = 0; var innerY = 0; - $element.on('mousedown', function (e) { + $element.on('pointerdown', function (e) { innerX = e.pageX + ($element.parent().width() - $element.width() - this.offsetLeft); innerY = e.pageY - this.offsetTop; - function mouseMoveCallback(e) { + function pointerMoveCallback(e) { position.right = innerX - e.pageX; position.top = e.pageY - innerY; delete position.isDefault; @@ -74,9 +74,9 @@ top: position.top }); } - $(document).on('mousemove', mouseMoveCallback) - .one('mouseup', function () { - $(document).off('mousemove', mouseMoveCallback); + $(document).on('pointermove', pointerMoveCallback) + .one('pointerup', function () { + $(document).off('pointermove', pointerMoveCallback); }); }); } diff --git a/style/client.css b/style/client.css index 209636cfaf..80ed47b035 100644 --- a/style/client.css +++ b/style/client.css @@ -1219,6 +1219,7 @@ a.ilink.yours { overflow: hidden; transition: max-height 0.15s; -webkit-transition: max-height 0.15s; + touch-action: none; } .tournament-bracket { @@ -1226,15 +1227,19 @@ a.ilink.yours { padding: 10px; overflow: hidden; font-size: 8pt; + touch-action: none; } + .tournament-bracket-overflowing { height: 200px; padding: 0; position: relative; left: 0; top: 0; + touch-action: none; } + .tournament-popout-link { position: absolute; bottom: 0.5em; diff --git a/style/client2.css b/style/client2.css index 8e46d6c08d..4a3b259120 100644 --- a/style/client2.css +++ b/style/client2.css @@ -1147,6 +1147,7 @@ a.ilink.yours { overflow: hidden; transition: max-height 0.15s; -webkit-transition: max-height 0.15s; + touch-action: none; } .tournament-bracket { @@ -1154,6 +1155,7 @@ a.ilink.yours { padding: 10px; overflow: hidden; font-size: 8pt; + touch-action: none; } .tournament-bracket-overflowing { height: 200px; @@ -1161,6 +1163,7 @@ a.ilink.yours { position: relative; left: 0; top: 0; + touch-action: none; } .tournament-popout-link { From cc9f6ae7df9ced8b8194cbd3165c0a30eff95379 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 15 Nov 2023 23:56:31 +0000 Subject: [PATCH 557/770] Make Replays work better on database failures I haven't done anything about the database issues, yet, but this makes it so database issues don't screw up the UI, and also gives a slightly nicer error message. --- replay.pokemonshowdown.com/index.template.php | 2 - replay.pokemonshowdown.com/replay.php | 64 ------------------- replay.pokemonshowdown.com/replays.lib.php | 3 +- .../src/replays-battle.tsx | 47 ++++++++------ 4 files changed, 29 insertions(+), 87 deletions(-) delete mode 100644 replay.pokemonshowdown.com/replay.php diff --git a/replay.pokemonshowdown.com/index.template.php b/replay.pokemonshowdown.com/index.template.php index 2e7c13ceac..b27fbe386c 100644 --- a/replay.pokemonshowdown.com/index.template.php +++ b/replay.pokemonshowdown.com/index.template.php @@ -20,8 +20,6 @@ $manage = false; -require_once 'replays.lib.php'; - $replay = null; $id = $_REQUEST['name'] ?? ''; $password = ''; diff --git a/replay.pokemonshowdown.com/replay.php b/replay.pokemonshowdown.com/replay.php deleted file mode 100644 index fb35465066..0000000000 --- a/replay.pokemonshowdown.com/replay.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @license MIT - */ - -error_reporting(E_ALL); -ini_set('display_errors', TRUE); -ini_set('display_startup_errors', TRUE); - -$manage = false; - -require_once 'replays.lib.php'; - -$replay = null; -$id = $_REQUEST['name'] ?? ''; -$password = ''; - -$fullid = $id; -if (substr($id, -2) === 'pw') { - $dashpos = strrpos($id, '-'); - $password = substr($id, $dashpos + 1, -2); - $id = substr($id, 0, $dashpos); - // die($id . ' ' . $password); -} - -// $forcecache = isset($_REQUEST['forcecache8723']); -$forcecache = false; -if ($id) { - if (file_exists('caches/' . $id . '.inc.php')) { - include 'caches/' . $id . '.inc.php'; - $replay['formatid'] = ''; - $cached = true; - } else { - require_once 'replays.lib.php'; - if (!$Replays->db && !$forcecache) { - header('HTTP/1.1 503 Service Unavailable'); - die(); - } - $replay = $Replays->exists($id, $forcecache); - } -} -if (!$replay) { - header('HTTP/1.1 404 Not Found'); - include '404.html'; - die(); -} -if ($replay['password'] ?? null) { - if ($password !== $replay['password']) { - header('HTTP/1.1 404 Not Found'); - include '404.html'; - die(); - } -} - -include 'index.html'; diff --git a/replay.pokemonshowdown.com/replays.lib.php b/replay.pokemonshowdown.com/replays.lib.php index db8cf32f90..7d2e34e827 100644 --- a/replay.pokemonshowdown.com/replays.lib.php +++ b/replay.pokemonshowdown.com/replays.lib.php @@ -24,7 +24,8 @@ function init() { ); } catch (PDOException $e) { // this error message contains the database password for some reason :| - die("Could not connect"); + header('HTTP/1.1 503 Service Unavailable'); + die("Database overloaded, please try again later"); } $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); diff --git a/replay.pokemonshowdown.com/src/replays-battle.tsx b/replay.pokemonshowdown.com/src/replays-battle.tsx index bfb0264ba6..4292f8cf41 100644 --- a/replay.pokemonshowdown.com/src/replays-battle.tsx +++ b/replay.pokemonshowdown.com/src/replays-battle.tsx @@ -70,6 +70,7 @@ export class BattlePanel extends preact.Component<{id: string}> { private: number; password: string; } | null | undefined = undefined; + resultError = ''; battle: Battle | null; /** debug purposes */ lastUsedKeyCode = '0'; @@ -92,17 +93,21 @@ export class BattlePanel extends preact.Component<{id: string}> { if (this.battle) this.battle.destroy(); this.battle = null; this.result = undefined; + this.resultError = ''; + this.forceUpdate(); const elem = document.getElementById(`replaydata-${id}`); if (elem) { - this.loadResult(elem.innerText, id); + // we actually do need to wait for that update to finish so + // loadResult definitely has access to $frame and $logFrame + setTimeout(() => this.loadResult(elem.innerText, id), 1); return; } Net(`/${this.stripQuery(id)}.json`).get().then(result => { this.loadResult(result, id); - }).catch(_ => { - this.loadResult('', id); + }).catch(err => { + this.loadResult(err.statusCode === 404 ? '' : String(err?.body || ''), id); }); } loadResult(result: string, id: string) { @@ -131,8 +136,9 @@ export class BattlePanel extends preact.Component<{id: string}> { if (query.turn || query.t) { this.battle.seekTurn(parseInt(query.turn || query.t, 10)); } - } catch { + } catch (err) { this.result = null; + this.resultError = result.startsWith('{') ? err.toString() : result; } this.forceUpdate(); } @@ -353,20 +359,21 @@ export class BattlePanel extends preact.Component<{id: string}> { e?.preventDefault(); this.forceUpdate(); }; - renderNotFound() { - return
    - {/*
    - - - -
    -
    - - - - - -
    */} + renderError(position: any) { + if (this.resultError) { + return
    +

    Error

    +

    + {this.resultError} +

    +
    ; + } + + // In theory, this should almost never happen, because Replays will + // never link to a nonexistent replay, but this might happen if e.g. + // a replay gets deleted or made private after you searched for it + // but before you clicked it. + return
    @@ -493,8 +500,6 @@ export class BattlePanel extends preact.Component<{id: string}> {
    ; } override render() { - if (this.result === null) return this.renderNotFound(); - let position: any = {}; if (PSRouter.showingLeft()) { if (PSRouter.stickyRight) { @@ -504,6 +509,8 @@ export class BattlePanel extends preact.Component<{id: string}> { } } + if (this.result === null) return this.renderError(position); + return
    From 9d8655c367136f55d36eb9ba9508177f130cb1d8 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Thu, 16 Nov 2023 00:00:07 +0000 Subject: [PATCH 558/770] Remove references to the old logo --- favicon-128.png | Bin 19210 -> 0 bytes favicon-192.png | Bin 39810 -> 0 bytes favicon-48.png | Bin 5612 -> 0 bytes js/client-topbar.js | 2 +- manifest.json | 9 ++------- showdown.webapp | 3 +-- 6 files changed, 4 insertions(+), 10 deletions(-) delete mode 100644 favicon-128.png delete mode 100644 favicon-192.png delete mode 100644 favicon-48.png diff --git a/favicon-128.png b/favicon-128.png deleted file mode 100644 index 69fc8cccc5649391000395ec8fbf77b9a44dc52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19210 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

    Yu(C@Zlk|W5pu*N_@oq4D=xu@}vsQi0ulf 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 diff --git a/js/client-topbar.js b/js/client-topbar.js index 635bfd5987..2c702a8784 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -199,7 +199,7 @@ for (var i in app.rooms) { if (app.rooms[i] !== app.curRoom && app.rooms[i].notificationClass === ' notifying') notificationClass = ' notifying'; } - var buf = '

    • Pokémon Showdown! (beta)
    '; + var buf = '
    • Pokémon Showdown! (beta)
    '; buf += '
      ' + this.renderRoomTab(app.curRoom) + '
    '; diff --git a/manifest.json b/manifest.json index 6fccbad744..a0f8b8744f 100644 --- a/manifest.json +++ b/manifest.json @@ -8,14 +8,9 @@ "sizes": "16x16" }, { - "src": "favicon-48.png", + "src": "favicon-32.png", "type": "image/png", - "sizes": "48x48" - }, - { - "src": "favicon-192.png", - "type": "image/png", - "sizes": "192x192" + "sizes": "32x32" }, { "src": "favicon-256.png", diff --git a/showdown.webapp b/showdown.webapp index 94e7b0a7b2..47f98fc7da 100644 --- a/showdown.webapp +++ b/showdown.webapp @@ -6,8 +6,7 @@ "icons": { "16": "/favicon-16.png", "32": "/favicon-32.png", - "48": "/favicon-48.png", - "128": "/favicon-128.png" + "256": "/favicon-256.png" }, "developer": { "name": "Guangcong Luo", From 426656e5e3f129f26a7dde17d2f0efee0519d001 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Thu, 16 Nov 2023 00:01:30 +0000 Subject: [PATCH 559/770] Don't default https://localhost.psim.us to HTTPS Anyone who wants to test on HTTPS can use localhost-443.psim.us. This can help with the issue where browsers prefer HTTPS over HTTP. There was an actual Cloudflare issue that made HTTP straight-up stop working for a while, but that one appears to be fixed now. --- js/clean-cookies.php | 2 +- js/client.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/js/clean-cookies.php b/js/clean-cookies.php index 10aa87c229..9086d78ecb 100644 --- a/js/clean-cookies.php +++ b/js/clean-cookies.php @@ -17,5 +17,5 @@ } if ($cleaned) { - echo 'alert("You had a cookie which was too big to handle and had to be deleted. If you had cookie settings, they may not be right.")'; + echo 'alert("You had a cookie which was too big to handle and had to be deleted. If you had cookie settings, they may have been deleted.")'; } diff --git a/js/client.js b/js/client.js index d32ae53e9d..4ab58ca347 100644 --- a/js/client.js +++ b/js/client.js @@ -756,6 +756,12 @@ function toId() { var self = this; var constructSocket = function () { + if (location.host === 'localhost.psim.us' || /[0-9]+.[0-9]+.[0-9]+.[0-9]+\.psim\.us/.test(location.host)) { + // normally we assume HTTPS means HTTPS, but make an exception for + // localhost and IPs which generally can't have a signed cert anyway. + Config.server.port = 8000; + Config.server.https = false; + } var protocol = (Config.server.port === 443 || Config.server.https) ? 'https' : 'http'; Config.server.host = $.trim(Config.server.host); try { From f1a74eb862e1f6668e23fafb5d12b9fe481942db Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 15 Nov 2023 19:34:45 -0700 Subject: [PATCH 560/770] Tooltips: Fix Low Kick BP in Gen 1/2 (#2186) --- src/battle-tooltips.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index 87bf0fe4b6..f85a4cbdf1 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1814,7 +1814,7 @@ class BattleTooltips { } } // Moves which have base power changed according to weight - if (['lowkick', 'grassknot', 'heavyslam', 'heatcrash'].includes(move.id)) { + if (['lowkick', 'grassknot', 'heavyslam', 'heatcrash'].includes(move.id) && this.battle.gen > 2) { let isGKLK = ['lowkick', 'grassknot'].includes(move.id); if (target) { let targetWeight = target.getWeightKg(); From 8358265598d350c8e9504b9b5b05b768b59dd0db Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 15 Nov 2023 19:35:59 -0700 Subject: [PATCH 561/770] Fix formats not found message not appearing (#2170) --- js/client-mainmenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/client-mainmenu.js b/js/client-mainmenu.js index 3267a20e28..e815e834f6 100644 --- a/js/client-mainmenu.js +++ b/js/client-mainmenu.js @@ -1320,7 +1320,7 @@ ); } var html = ''; - if (!bufs.length) { + if (bufs.every(function (buf) { return !buf; })) { html = '
      No formats found
    '; } else { for (var i = 1, l = bufs.length; i < l; i++) { From 077b762384b4fc13b4fc8cbf7c64ae49e027f80f Mon Sep 17 00:00:00 2001 From: pyuk-bot Date: Wed, 15 Nov 2023 20:36:37 -0600 Subject: [PATCH 562/770] Tooltips: show Tera BP floor (#2153) --- src/battle-tooltips.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/battle-tooltips.ts b/src/battle-tooltips.ts index f85a4cbdf1..25afd06907 100644 --- a/src/battle-tooltips.ts +++ b/src/battle-tooltips.ts @@ -1993,6 +1993,18 @@ class BattleTooltips { if (move.id === 'risingvoltage' && this.battle.hasPseudoWeather('Electric Terrain') && target?.isGrounded()) { value.modify(2, 'Rising Voltage + Electric Terrain boost'); } + + // Item + value = this.getItemBoost(move, value, moveType); + + // Terastal base power floor + if ( + pokemon.terastallized && pokemon.terastallized === move.type && value.value < 60 && move.priority <= 0 && + !move.multihit && !((move.basePower === 0 || move.basePower === 150) && (move as any).basePowerCallback) + ) { + value.set(60, 'Tera type BP minimum'); + } + if ( move.id === 'steelroller' && !this.battle.hasPseudoWeather('Electric Terrain') && @@ -2003,9 +2015,6 @@ class BattleTooltips { value.set(0, 'no Terrain'); } - // Item - value = this.getItemBoost(move, value, moveType); - return value; } From a3fdd95493e1e874f47e75cdd6ba4d5e75edc998 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Thu, 16 Nov 2023 06:25:49 +0000 Subject: [PATCH 563/770] Add framebuster We originally let PS be embedded because I was happy to get more attention, but at this point it's no longer a good idea. (also add a logo update I missed from 9d8655c367136f5 ) --- index.template.html | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/index.template.html b/index.template.html index cc3ba8c76a..bf4837d243 100644 --- a/index.template.html +++ b/index.template.html @@ -29,7 +29,7 @@ Showdown! - + @@ -111,7 +111,15 @@

  • '; + bufs[curBuf] += '
  • '; count++; if (count % bufBoundary === 0 && curBuf < 4) curBuf++; } else { From f3500bc8e4af9ba7434d4f84bc8f883cde0ff8e8 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Thu, 16 Nov 2023 12:35:15 -0600 Subject: [PATCH 568/770] Fix 2FA authentication It was previously throwing errors about 'no client_id provided', this fixes that by the initialization code for auth2 first (suggested by several google results and confirmed to work by me.) --- play.pokemonshowdown.com/js/client-topbar.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/play.pokemonshowdown.com/js/client-topbar.js b/play.pokemonshowdown.com/js/client-topbar.js index 2c702a8784..3a92e03837 100644 --- a/play.pokemonshowdown.com/js/client-topbar.js +++ b/play.pokemonshowdown.com/js/client-topbar.js @@ -1086,6 +1086,26 @@ if (data.special === '@gmail') { var self = this; window.gapiRenderButton = function () { + if (!window.gapiAuthenticated) { + gapi.load('auth2', function () { // eslint-disable-line no-undef + window.gapiAuthenticated = gapi.auth2.init({ // eslint-disable-line no-undef + client_id: '912270888098-jjnre816lsuhc5clj3vbcn4o2q7p4qvk.apps.googleusercontent.com', + }); + window.gapiAuthenticated.then(function () { + window.gapiAuthenticated = true; + window.gapiRenderButton(); + }); + }); + return; + } + // they're trying again in a new popup, set a new .then so it still works + if (window.gapiAuthenticated.then) { + window.gapiAuthenticated.then(function () { + window.gapiAuthenticated = true; + window.gapiRenderButton(); + }); + return; + } gapi.signin2.render('gapi-custom-signin', { // eslint-disable-line no-undef 'scope': 'profile email', 'width': 240, From 4fa3ed7c33bc6e2a5808ff017cb4f9b895f0adf1 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:51:11 -0600 Subject: [PATCH 569/770] Build-tools: Always try to update news --- build-tools/update | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/build-tools/update b/build-tools/update index 1afb8bf73b..2cfedf191d 100755 --- a/build-tools/update +++ b/build-tools/update @@ -193,30 +193,26 @@ function updateFiles() { replayEmbedContents = replayEmbedContents.replace(/play\.pokemonshowdown\.com/g, routes.client); // add news, only if it's actually likely to exist - if (__dirname.endsWith('play.pokemonshowdown.com/build-tools')) { - process.stdout.write("and news... "); - child_process.exec('php ' + path.resolve(thisDir, 'news-data.php'), function (error, stdout, stderr) { - let newsData = [0, '[failed to retrieve news]']; - if (!error && !stderr) { - try { - newsData = JSON.parse(stdout); - } catch (e) { - console.log("git hook failed to retrieve news (parsing JSON failed):\n" + e.stack); - } - } else { - console.log("git hook failed to retrieve news (exec command failed):\n" + (error + stderr + stdout)); + process.stdout.write("and news... "); + child_process.exec('php ' + path.resolve(thisDir, 'news-data.php'), function (error, stdout, stderr) { + let newsData = [0, '[failed to retrieve news]']; + if (!error && !stderr) { + try { + newsData = JSON.parse(stdout); + } catch (e) { + console.log("git hook failed to retrieve news (parsing JSON failed):\n" + e.stack); } + } else { + console.log("git hook failed to retrieve news (exec command failed):\n" + (error + stderr + stdout)); + } - indexContents = indexContents.replace(//g, newsData[0]); - indexContents = indexContents.replace(//g, newsData[1]); + indexContents = indexContents.replace(//g, newsData[0]); + indexContents = indexContents.replace(//g, newsData[1]); - indexContents = indexContents.replace(//g, '' + fs.readFileSync('config/head-custom.html')); + indexContents = indexContents.replace(//g, '' + fs.readFileSync('config/head-custom.html')); - writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents); - }); - } else { writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents); - } + }); } updateFiles(); From 5b97740c802de10b53d43857de501a1d0b27c116 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Thu, 16 Nov 2023 13:16:32 +0000 Subject: [PATCH 570/770] Fix overlooked paths from directory reorg --- replay.pokemonshowdown.com/src/replays-battle.tsx | 6 +++--- test/parse | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/replay.pokemonshowdown.com/src/replays-battle.tsx b/replay.pokemonshowdown.com/src/replays-battle.tsx index 4292f8cf41..daa8325487 100644 --- a/replay.pokemonshowdown.com/src/replays-battle.tsx +++ b/replay.pokemonshowdown.com/src/replays-battle.tsx @@ -3,9 +3,9 @@ import preact from 'preact'; import $ from 'jquery'; import {Net} from './utils'; import {PSRouter, PSReplays} from './replays'; -import {Battle} from '../../src/battle'; -import {BattleLog} from '../../src/battle-log'; -import {BattleSound} from '../../src/battle-sound'; +import {Battle} from '../../play.pokemonshowdown.com/src/battle'; +import {BattleLog} from '../../play.pokemonshowdown.com/src/battle-log'; +import {BattleSound} from '../../play.pokemonshowdown.com/src/battle-sound'; declare function toID(input: string): string; function showAd(id: string) { diff --git a/test/parse b/test/parse index 00e48121a3..2183bfd94d 100755 --- a/test/parse +++ b/test/parse @@ -5,9 +5,9 @@ const path = require('path'); process.chdir(path.resolve(__dirname, '..')); -require(`../js/battle-dex.js`); // only needed for toID -global.BattleText = require(`../data/text.js`).BattleText; -require(`../js/battle-text-parser.js`); +require(`../play.pokemonshowdown.com/js/battle-dex.js`); // only needed for toID +global.BattleText = require(`../play.pokemonshowdown.com/data/text.js`).BattleText; +require(`../play.pokemonshowdown.com/js/battle-text-parser.js`); const parser = new BattleTextParser(); From d66b080873ba40e79d1a08f24d0133c5dc0fc47d Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Thu, 16 Nov 2023 22:59:34 +0000 Subject: [PATCH 571/770] Move replay-config to config/ I'm trying to centralize config. --- .gitignore | 3 +-- .../replay-config.example.inc.php | 0 replay.pokemonshowdown.com/replays.lib.php | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) rename {replay.pokemonshowdown.com => config}/replay-config.example.inc.php (100%) diff --git a/.gitignore b/.gitignore index 31fcc7ed53..119df30368 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,7 @@ package-lock.json /play.pokemonshowdown.com/index.html /play.pokemonshowdown.com/preactalpha.html /play.pokemonshowdown.com/crossprotocol.html -/play.pokemonshowdown.com/data/* +/play.pokemonshowdown.com/data/ /play.pokemonshowdown.com/js/server/ /play.pokemonshowdown.com/js/*.js.map @@ -33,5 +33,4 @@ package-lock.json /replay.pokemonshowdown.com/index.php /replay.pokemonshowdown.com/js/ /replay.pokemonshowdown.com/caches/ -/replay.pokemonshowdown.com/replay-config.inc.php /replay.pokemonshowdown.com/theme/wrapper.inc.php diff --git a/replay.pokemonshowdown.com/replay-config.example.inc.php b/config/replay-config.example.inc.php similarity index 100% rename from replay.pokemonshowdown.com/replay-config.example.inc.php rename to config/replay-config.example.inc.php diff --git a/replay.pokemonshowdown.com/replays.lib.php b/replay.pokemonshowdown.com/replays.lib.php index 7d2e34e827..86ab892706 100644 --- a/replay.pokemonshowdown.com/replays.lib.php +++ b/replay.pokemonshowdown.com/replays.lib.php @@ -1,6 +1,6 @@ Date: Thu, 16 Nov 2023 23:48:27 +0000 Subject: [PATCH 572/770] Refactor build tools for readability (Also fixes the build error.) --- build-tools/{news-data.php => news-embed.php} | 2 +- build-tools/update | 105 +++++++++--------- 2 files changed, 51 insertions(+), 56 deletions(-) rename build-tools/{news-data.php => news-embed.php} (69%) diff --git a/build-tools/news-data.php b/build-tools/news-embed.php similarity index 69% rename from build-tools/news-data.php rename to build-tools/news-embed.php index 16af212d43..a30352e441 100644 --- a/build-tools/news-data.php +++ b/build-tools/news-embed.php @@ -2,4 +2,4 @@ date_default_timezone_set('America/Los_Angeles'); include __DIR__.'/../pokemonshowdown.com/news/include.php'; -echo json_encode(array(getNewsId(), renderNews())); +echo json_encode([getNewsId(), renderNews()]); diff --git a/build-tools/update b/build-tools/update index 2cfedf191d..b255490cff 100755 --- a/build-tools/update +++ b/build-tools/update @@ -137,82 +137,77 @@ process.stdout.write("Updating cachebuster and URLs... "); const URL_REGEX = /(src|href)="(.*?)(\?[a-z0-9]*?)?"/g; -function updateURL(a, b, c, d) { - c = c.replace('/replay.pokemonshowdown.com/', '/' + routes.replays + '/'); - c = c.replace('/dex.pokemonshowdown.com/', '/' + routes.dex + '/'); - c = c.replace('/play.pokemonshowdown.com/', '/' + routes.client + '/'); - c = c.replace('/pokemonshowdown.com/', '/' + routes.root + '/'); - - if (d) { - if (c.startsWith('/')) { +function addCachebuster(_, attr, url, urlQuery) { + url = url.replace('/replay.pokemonshowdown.com/', '/' + routes.replays + '/'); + url = url.replace('/dex.pokemonshowdown.com/', '/' + routes.dex + '/'); + url = url.replace('/play.pokemonshowdown.com/', '/' + routes.client + '/'); + url = url.replace('/pokemonshowdown.com/', '/' + routes.root + '/'); + + if (urlQuery) { + if (url.startsWith('/')) { let hash = Math.random(); // just in case creating the hash fails try { - const filename = c.slice(1).replace('/' + routes.client + '/', ''); + const filename = url.slice(1).replace('/' + routes.client + '/', ''); const fstr = fs.readFileSync(filename, {encoding: 'utf8'}); hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8); } catch (e) {} - return b + '="' + c + '?' + hash + '"'; + return attr + '="' + url + '?' + hash + '"'; } else { // hardcoded to Replays rn; TODO: generalize let hash; try { - const fstr = fs.readFileSync('replay.pokemonshowdown.com/' + c, {encoding: 'utf8'}); + const fstr = fs.readFileSync('replay.pokemonshowdown.com/' + url, {encoding: 'utf8'}); hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8); } catch (e) {} - return b + '="' + c + '?' + (hash || 'v1') + '"'; + return attr + '="' + url + '?' + (hash || 'v1') + '"'; } } else { - return b + '="' + c + '"'; + return attr + '="' + url + '"'; } } -function writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents) { - fs.writeFileSync('play.pokemonshowdown.com/index.html', indexContents); - fs.writeFileSync('play.pokemonshowdown.com/preactalpha.html', preactIndexContents); - fs.writeFileSync('play.pokemonshowdown.com/crossprotocol.html', crossprotocolContents); - fs.writeFileSync('play.pokemonshowdown.com/js/replay-embed.js', replayEmbedContents); - - let replaysContents = fs.readFileSync('replay.pokemonshowdown.com/index.template.php', {encoding: 'utf8'}); - replaysContents = replaysContents.replace(URL_REGEX, updateURL); - fs.writeFileSync('replay.pokemonshowdown.com/index.php', replaysContents); - - console.log("DONE"); +// add hashes to js and css files and rewrite URLs +let indexContents = fs.readFileSync('play.pokemonshowdown.com/index.template.html', {encoding: 'utf8'}); +indexContents = indexContents.replace(URL_REGEX, addCachebuster); +let preactIndexContents = fs.readFileSync('play.pokemonshowdown.com/preactalpha.template.html', {encoding: 'utf8'}); +preactIndexContents = preactIndexContents.replace(URL_REGEX, addCachebuster); +let crossprotocolContents = fs.readFileSync('play.pokemonshowdown.com/crossprotocol.template.html', {encoding: 'utf8'}); +crossprotocolContents = crossprotocolContents.replace(URL_REGEX, addCachebuster); +let replayEmbedContents = fs.readFileSync('play.pokemonshowdown.com/js/replay-embed.template.js', {encoding: 'utf8'}); +replayEmbedContents = replayEmbedContents.replace(/play\.pokemonshowdown\.com/g, routes.client); + +// add news, only if it's actually likely to exist +process.stdout.write("and news... "); +let stdout = ''; +let newsid = 0; +let news = '[failed to retrieve news]'; +try { + stdout = child_process.execSync('php ' + path.resolve(thisDir, 'news-embed.php')); +} catch (e) { + console.log("git hook failed to retrieve news (exec command failed):\n" + (e.error + e.stderr + e.stdout)); +} +try { + if (stdout) [newsid, news] = JSON.parse(stdout); +} catch (e) { + console.log("git hook failed to retrieve news (parsing JSON failed):\n" + e.stack); } -function updateFiles() { - // add hashes to js and css files and rewrite URLs - let indexContents = fs.readFileSync('play.pokemonshowdown.com/index.template.html', {encoding: 'utf8'}); - indexContents = indexContents.replace(URL_REGEX, updateURL); - let preactIndexContents = fs.readFileSync('play.pokemonshowdown.com/preactalpha.template.html', {encoding: 'utf8'}); - preactIndexContents = preactIndexContents.replace(URL_REGEX, updateURL); - let crossprotocolContents = fs.readFileSync('play.pokemonshowdown.com/crossprotocol.template.html', {encoding: 'utf8'}); - crossprotocolContents = crossprotocolContents.replace(URL_REGEX, updateURL); - let replayEmbedContents = fs.readFileSync('play.pokemonshowdown.com/js/replay-embed.template.js', {encoding: 'utf8'}); - replayEmbedContents = replayEmbedContents.replace(/play\.pokemonshowdown\.com/g, routes.client); - - // add news, only if it's actually likely to exist - process.stdout.write("and news... "); - child_process.exec('php ' + path.resolve(thisDir, 'news-data.php'), function (error, stdout, stderr) { - let newsData = [0, '[failed to retrieve news]']; - if (!error && !stderr) { - try { - newsData = JSON.parse(stdout); - } catch (e) { - console.log("git hook failed to retrieve news (parsing JSON failed):\n" + e.stack); - } - } else { - console.log("git hook failed to retrieve news (exec command failed):\n" + (error + stderr + stdout)); - } +indexContents = indexContents.replace(//g, newsid); +indexContents = indexContents.replace(//g, news); - indexContents = indexContents.replace(//g, newsData[0]); - indexContents = indexContents.replace(//g, newsData[1]); +try { + indexContents = indexContents.replace(//g, '' + fs.readFileSync('config/head-custom.html')); +} catch {} - indexContents = indexContents.replace(//g, '' + fs.readFileSync('config/head-custom.html')); +fs.writeFileSync('play.pokemonshowdown.com/index.html', indexContents); +fs.writeFileSync('play.pokemonshowdown.com/preactalpha.html', preactIndexContents); +fs.writeFileSync('play.pokemonshowdown.com/crossprotocol.html', crossprotocolContents); +fs.writeFileSync('play.pokemonshowdown.com/js/replay-embed.js', replayEmbedContents); - writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents); - }); -} +let replaysContents = fs.readFileSync('replay.pokemonshowdown.com/index.template.php', {encoding: 'utf8'}); +replaysContents = replaysContents.replace(URL_REGEX, addCachebuster); +fs.writeFileSync('replay.pokemonshowdown.com/index.php', replaysContents); -updateFiles(); +console.log("DONE"); From bd134f4ccf541378979cc4395458ed2949299468 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Thu, 16 Nov 2023 23:50:37 +0000 Subject: [PATCH 573/770] Fix crash in customcss (Introduced in - you guessed it - the directory reorg.) --- play.pokemonshowdown.com/customcss.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/play.pokemonshowdown.com/customcss.php b/play.pokemonshowdown.com/customcss.php index 14a0b39f0f..bbe9ca4be5 100644 --- a/play.pokemonshowdown.com/customcss.php +++ b/play.pokemonshowdown.com/customcss.php @@ -2,11 +2,11 @@ ini_set('max_execution_time', 60); // 1 minute -require_once __DIR__ . '/config/config.inc.php'; -require_once __DIR__ . '/config/servers.inc.php'; +require_once __DIR__ . '/../config/config.inc.php'; +require_once __DIR__ . '/../config/servers.inc.php'; spl_autoload_register(function ($class) { - require_once('lib/css-sanitizer/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'); + require_once(__DIR__ . '/../lib/css-sanitizer/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'); }); use Wikimedia\CSS\Parser\Parser; @@ -32,7 +32,7 @@ } // No need to sanitise $server because it should be safe already. -$cssfile = __DIR__ . '/config/customcss/' . $server . '.css'; +$cssfile = __DIR__ . '/../config/customcss/' . $server . '.css'; $lastmodified = @filemtime($cssfile); $timenow = time(); From 49cb741f101dd583a47c41ad3b7fbba291960cd5 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Fri, 17 Nov 2023 00:28:40 +0000 Subject: [PATCH 574/770] Move Analytics/ads into config This stuff isn't really relevant to anyone trying to develop at home, anyway. --- .gitignore | 2 + play.pokemonshowdown.com/ads.txt | 1 - pokemonshowdown.com/index.php | 65 ++++++-------------------------- 3 files changed, 13 insertions(+), 55 deletions(-) delete mode 100644 play.pokemonshowdown.com/ads.txt diff --git a/.gitignore b/.gitignore index 119df30368..cf2bac8815 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ package-lock.json /play.pokemonshowdown.com/js/client-main.js /play.pokemonshowdown.com/js/client-core.js /play.pokemonshowdown.com/js/client-connection.js +/play.pokemonshowdown.com/ads.txt /pokemonshowdown.com/.well-known/ /pokemonshowdown.com/.pages-cached/ @@ -34,3 +35,4 @@ package-lock.json /replay.pokemonshowdown.com/js/ /replay.pokemonshowdown.com/caches/ /replay.pokemonshowdown.com/theme/wrapper.inc.php +/replay.pokemonshowdown.com/ads.txt diff --git a/play.pokemonshowdown.com/ads.txt b/play.pokemonshowdown.com/ads.txt deleted file mode 100644 index 0a7f85be06..0000000000 --- a/play.pokemonshowdown.com/ads.txt +++ /dev/null @@ -1 +0,0 @@ -google.com, pub-6535472412829264, DIRECT, f08c47fec0942fa0 diff --git a/pokemonshowdown.com/index.php b/pokemonshowdown.com/index.php index 4aa0f83a6c..307f4cdca9 100644 --- a/pokemonshowdown.com/index.php +++ b/pokemonshowdown.com/index.php @@ -1,6 +1,3 @@ - @@ -10,16 +7,11 @@ - - - - + - -
    - -
    - Loading... -
    -
    - - - - -
    -

    - This graph shows the number of users on the official server. By default, the last 3 days are shown. - The most users ever recorded online at once was users on . - Times are displayed as UTC, which is probably your local timezone. -

    -
    -
    -
    -

    Click and drag a section of the overview below to view an arbitrary time period:

    -
    - - - - - - - - From 5e328964619d42a333d0efc17a76afb0e977b754 Mon Sep 17 00:00:00 2001 From: Christopher Monsanto Date: Sat, 16 Mar 2024 18:35:20 -0400 Subject: [PATCH 654/770] One more --- pokemonshowdown.com/credits.php | 1 - 1 file changed, 1 deletion(-) diff --git a/pokemonshowdown.com/credits.php b/pokemonshowdown.com/credits.php index 2d84d24f13..3b882d3719 100644 --- a/pokemonshowdown.com/credits.php +++ b/pokemonshowdown.com/credits.php @@ -68,7 +68,6 @@
    • Bill Meltsner [bmelts] – Development, Sysadmin

    • -
    • [bumbadadabum] – Development

    • Hugh Gordon [V4, DanUgore] – Research (game mechanics), Development

    • Juanma Serrano [Joim] – Development, Sysadmin

    • Leonardo Julca [Slayer95] – Development

    • From 946f69954877405b8bbabe6d45249213d9358904 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sat, 23 Mar 2024 10:18:59 +0000 Subject: [PATCH 655/770] Improve dark mode checkboxes --- play.pokemonshowdown.com/style/battle-log.css | 5 +++++ play.pokemonshowdown.com/style/battle.css | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/style/battle-log.css b/play.pokemonshowdown.com/style/battle-log.css index 3b21c88f9d..2a48690f87 100644 --- a/play.pokemonshowdown.com/style/battle-log.css +++ b/play.pokemonshowdown.com/style/battle-log.css @@ -255,6 +255,11 @@ select.button { * Forms *********************************************************/ +.dark { + /* we already have custom scrollbars/buttons so this is really just checkboxes */ + color-scheme: dark; +} + .label { font-size: 9pt; font-weight: bold; diff --git a/play.pokemonshowdown.com/style/battle.css b/play.pokemonshowdown.com/style/battle.css index 12e39208e7..2b82caae7b 100644 --- a/play.pokemonshowdown.com/style/battle.css +++ b/play.pokemonshowdown.com/style/battle.css @@ -5,7 +5,7 @@ License: GPLv2 */ -@import url(./battle-log.css?v6.5); +@import url(./battle-log.css?v6.6); .battle { position: absolute; From b01c15080f658507c03071c817bd5ea06067885e Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Sun, 24 Mar 2024 19:56:23 -0700 Subject: [PATCH 656/770] Let's Go: Support itemless megas (#2233) --- play.pokemonshowdown.com/js/client-battle.js | 29 ++++++++++++++++++- .../js/client-teambuilder.js | 3 +- .../src/battle-choices.ts | 16 +++++++++- play.pokemonshowdown.com/src/panel-battle.tsx | 18 ++++++++++++ 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/play.pokemonshowdown.com/js/client-battle.js b/play.pokemonshowdown.com/js/client-battle.js index 5a03645c41..95db81614a 100644 --- a/play.pokemonshowdown.com/js/client-battle.js +++ b/play.pokemonshowdown.com/js/client-battle.js @@ -53,6 +53,8 @@ }, events: { 'click .replayDownloadButton': 'clickReplayDownloadButton', + 'change input[name=megaevox]': 'uncheckMegaEvoY', + 'change input[name=megaevoy]': 'uncheckMegaEvoX', 'change input[name=zmove]': 'updateZMove', 'change input[name=dynamax]': 'updateMaxMove' }, @@ -510,6 +512,12 @@ } return ''; }, + uncheckMegaEvoX: function () { + this.$('input[name=megaevox]').prop('checked', false); + }, + uncheckMegaEvoY: function () { + this.$('input[name=megaevoy]').prop('checked', false); + }, updateMaxMove: function () { var dynaChecked = this.$('input[name=dynamax]')[0].checked; if (dynaChecked) { @@ -559,6 +567,8 @@ if (!curActive) return; var trapped = curActive.trapped; var canMegaEvo = curActive.canMegaEvo || switchables[pos].canMegaEvo; + var canMegaEvoX = curActive.canMegaEvoX || switchables[pos].canMegaEvoX; + var canMegaEvoY = curActive.canMegaEvoY || switchables[pos].canMegaEvoY; var canZMove = curActive.canZMove || switchables[pos].canZMove; var canUltraBurst = curActive.canUltraBurst || switchables[pos].canUltraBurst; var canDynamax = curActive.canDynamax || switchables[pos].canDynamax; @@ -721,6 +731,13 @@ } if (canMegaEvo) { moveMenu += '
      '; + } else if (canMegaEvoX && canMegaEvoY) { + moveMenu += '
      '; + moveMenu += ''; + } else if (canMegaEvoX) { + moveMenu += '
      '; + } else if (canMegaEvoY) { + moveMenu += '
      '; } else if (canZMove) { moveMenu += '
      '; } else if (canUltraBurst) { @@ -983,6 +1000,14 @@ buf += 'Mega Evolve, then '; targetPos = parts[3]; } + if (targetPos === 'megax') { + buf += 'Mega Evolve X, then '; + targetPos = parts[3]; + } + if (targetPos === 'megay') { + buf += 'Mega Evolve Y, then '; + targetPos = parts[3]; + } if (targetPos === 'zmove') { move = this.request.active[i].canZMove[parseInt(parts[1], 10) - 1].move; targetPos = parts[3]; @@ -1232,6 +1257,8 @@ if (pos !== undefined) { // pos === undefined if called by chooseMoveTarget() var nearActive = this.battle.nearSide.active; var isMega = !!(this.$('input[name=megaevo]')[0] || '').checked; + var isMegaX = !!(this.$('input[name=megaevox]')[0] || '').checked; + var isMegaY = !!(this.$('input[name=megaevoy]')[0] || '').checked; var isZMove = !!(this.$('input[name=zmove]')[0] || '').checked; var isUltraBurst = !!(this.$('input[name=ultraburst]')[0] || '').checked; var isDynamax = !!(this.$('input[name=dynamax]')[0] || '').checked; @@ -1240,7 +1267,7 @@ var target = e.getAttribute('data-target'); var choosableTargets = {normal: 1, any: 1, adjacentAlly: 1, adjacentAllyOrSelf: 1, adjacentFoe: 1}; - this.choice.choices.push('move ' + pos + (isMega ? ' mega' : '') + (isZMove ? ' zmove' : '') + (isUltraBurst ? ' ultra' : '') + (isDynamax ? ' dynamax' : '') + (isTerastal ? ' terastallize' : '')); + this.choice.choices.push('move ' + pos + (isMega ? ' mega' : '') + (isMegaX ? ' megax' : isMegaY ? ' megay' : '') + (isZMove ? ' zmove' : '') + (isUltraBurst ? ' ultra' : '') + (isDynamax ? ' dynamax' : '') + (isTerastal ? ' terastallize' : '')); if (nearActive.length > 1 && target in choosableTargets) { this.choice.type = 'movetarget'; this.choice.moveTarget = target; diff --git a/play.pokemonshowdown.com/js/client-teambuilder.js b/play.pokemonshowdown.com/js/client-teambuilder.js index 170cf69752..474e27497a 100644 --- a/play.pokemonshowdown.com/js/client-teambuilder.js +++ b/play.pokemonshowdown.com/js/client-teambuilder.js @@ -1364,8 +1364,7 @@ buf += ''; buf += '
      '; - // if (this.curTeam.gen > 1 && !isLetsGo) buf += '
      '; - if (this.curTeam.gen > 1) buf += '
      '; + if (this.curTeam.gen > 1 && !isLetsGo) buf += '
      '; if (this.curTeam.gen > 2 && !isLetsGo) buf += '
      '; buf += '
      '; diff --git a/play.pokemonshowdown.com/src/battle-choices.ts b/play.pokemonshowdown.com/src/battle-choices.ts index ac19db6a06..e44fd75a80 100644 --- a/play.pokemonshowdown.com/src/battle-choices.ts +++ b/play.pokemonshowdown.com/src/battle-choices.ts @@ -41,6 +41,8 @@ interface BattleRequestActivePokemon { canDynamax?: boolean; canGigantamax?: boolean; canMegaEvo?: boolean; + canMegaEvoX?: boolean; + canMegaEvoY?: boolean; canUltraBurst?: boolean; canTerastallize?: boolean; trapped?: boolean; @@ -82,6 +84,8 @@ interface BattleMoveChoice { move: number; targetLoc: number; mega: boolean; + megax: boolean; + megay: boolean; ultra: boolean; max: boolean; z: boolean; @@ -114,6 +118,8 @@ class BattleChoiceBuilder { move: 0, targetLoc: 0, // should always be 0: is not partial if `targetLoc` is known mega: false, + megax: false, + megay: false, ultra: false, z: false, max: false, @@ -194,7 +200,7 @@ class BattleChoiceBuilder { return null; } } - if (choice.mega) this.alreadyMega = true; + if (choice.mega || choice.megax || choice.megay) this.alreadyMega = true; if (choice.z) this.alreadyZ = true; if (choice.max) this.alreadyMax = true; if (choice.tera) this.alreadyTera = true; @@ -285,6 +291,8 @@ class BattleChoiceBuilder { move: 0, targetLoc: 0, mega: false, + megax: false, + megay: false, ultra: false, z: false, max: false, @@ -302,6 +310,12 @@ class BattleChoiceBuilder { } else if (choice.endsWith(' mega')) { current.mega = true; choice = choice.slice(0, -5); + } else if (choice.endsWith(' megax')) { + current.megax = true; + choice = choice.slice(0, -6); + } else if (choice.endsWith(' megay')) { + current.megay = true; + choice = choice.slice(0, -6); } else if (choice.endsWith(' zmove')) { current.z = true; choice = choice.slice(0, -6); diff --git a/play.pokemonshowdown.com/src/panel-battle.tsx b/play.pokemonshowdown.com/src/panel-battle.tsx index 3c9c0d8783..6e6d40a1c8 100644 --- a/play.pokemonshowdown.com/src/panel-battle.tsx +++ b/play.pokemonshowdown.com/src/panel-battle.tsx @@ -245,6 +245,14 @@ class BattlePanel extends PSRoomPanel { case 'mega': choices.current.mega = checkbox.checked; break; + case 'megax': + choices.current.megax = checkbox.checked; + choices.current.megay = false; + break; + case 'megay': + choices.current.megay = checkbox.checked; + choices.current.megax = false; + break; case 'ultra': choices.current.ultra = checkbox.checked; break; @@ -549,6 +557,8 @@ class BattlePanel extends PSRoomPanel { const canDynamax = moveRequest.canDynamax && !choices.alreadyMax; const canMegaEvo = moveRequest.canMegaEvo && !choices.alreadyMega; + const canMegaEvoX = moveRequest.canMegaEvoX && !choices.alreadyMega; + const canMegaEvoY = moveRequest.canMegaEvoY && !choices.alreadyMega; const canZMove = moveRequest.zMoves && !choices.alreadyZ; if (choices.current.move) { @@ -588,6 +598,14 @@ class BattlePanel extends PSRoomPanel { {} Mega Evolution } + {canMegaEvoX && } + {canMegaEvoY && } {moveRequest.canUltraBurst &&

      '; buf += '

      '; buf += '

      '; } @@ -283,11 +284,13 @@ }, selectTeammate: function (e) { - if (e.currentTarget.name !== 'teammate' || e.keyCode !== 13) return; - var partner = toID(e.currentTarget.value); + e.stopPropagation(); + e.preventDefault(); + var input = $('input.partnerselect').get(0); + var partner = toID(input.value); if (!partner.length) return; app.send('/requestpartner ' + partner + ',' + this.curFormat); - e.currentTarget.value = ''; + input.value = ""; }, openPM: function (name, dontFocus) { From 9434aed35be470dd02234e9c96dde6e0d7fa0dde Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sat, 4 May 2024 12:02:01 -0600 Subject: [PATCH 668/770] Add SSB client support (#2245) * ssb support * SSB * teehee * poop * more tooltip things * Fix tooltips * ok support * More tooltip updates * last changes * Fix build --- build-tools/build-indexes | 11 +- .../src/battle-animations.ts | 1 + .../src/battle-tooltips.ts | 353 +++++++++++++++--- play.pokemonshowdown.com/src/battle.ts | 18 + 4 files changed, 334 insertions(+), 49 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 01e935a45b..ab08227c74 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -322,7 +322,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const LC = GENS.map(num => num + 0.7); const STADIUM = [2.04, 1.04]; const NATDEX = [9.1, 8.1]; - const OTHER = [9.9, 9.411, 9.41, 9.401, 9.4, 9.2, -9.4, -9.401, 8.6, 8.4, 8.2, 8.1, -8.4, -8.6, 7.1]; + const OTHER = [9.9, 9.6, 9.411, 9.41, 9.401, 9.4, 9.2, -9.4, -9.401, 8.6, 8.4, 8.2, 8.1, -8.4, -8.6, 7.1]; // process.stdout.write("\n "); for (const genIdent of [...GENS, ...DOUBLES, ...VGC, ...NFE, ...STADIUM, ...OTHER, ...NATDEX, ...LC]) { @@ -339,6 +339,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const isDoubles = (genIdent < 0); const isVGC = ('' + genIdent).endsWith('.5'); const isGen9BH = genIdent === 9.9; + const isSSB = genIdent === 9.6; const genNum = Math.floor(isDoubles ? -genIdent : genIdent); const gen = (() => { let genStr = 'gen' + genNum; @@ -348,6 +349,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (isPreDLC) genStr += 'predlc'; if (isSVDLC1) genStr += 'dlc1'; if (isStadium) genStr += 'stadium' + (genNum > 1 ? genNum : ''); + if (isSSB) genStr += 'ssb'; return genStr; })(); // process.stdout.write("" + gen + (isDoubles ? " doubles" : "") + "... "); @@ -543,6 +545,11 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable['bh'].tiers = tiers; BattleTeambuilderTable['bh'].overrideTier = overrideTier; BattleTeambuilderTable['bh'].formatSlices = formatSlices; + } else if (isSSB) { + BattleTeambuilderTable['gen9ssb'] = {}; + BattleTeambuilderTable['gen9ssb'].tiers = tiers; + BattleTeambuilderTable['gen9ssb'].overrideTier = overrideTier; + BattleTeambuilderTable['gen9ssb'].formatSlices = formatSlices; } else if (gen === 'gen9') { BattleTeambuilderTable.tiers = tiers; BattleTeambuilderTable.items = items; @@ -1148,7 +1155,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); // Mods // - for (const mod of ['gen7letsgo', 'gen8bdsp']) { + for (const mod of ['gen7letsgo', 'gen8bdsp', 'gen9ssb']) { const modDex = Dex.mod(mod); const modData = modDex.data; const parentDex = Dex.forGen(modDex.gen); diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index 31087b3da5..3cd37baca4 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -122,6 +122,7 @@ export class BattleScene implements BattleSceneStub { } this.numericId = numericId; this.tooltips = new BattleTooltips(battle); + if (this.battle.id.includes('superstaffbros')) this.tooltips.dex = Dex.mod('gen9ssb' as ID); this.tooltips.listen($frame[0]); this.preloadEffects(); diff --git a/play.pokemonshowdown.com/src/battle-tooltips.ts b/play.pokemonshowdown.com/src/battle-tooltips.ts index 0aa73f73f9..1805628fac 100644 --- a/play.pokemonshowdown.com/src/battle-tooltips.ts +++ b/play.pokemonshowdown.com/src/battle-tooltips.ts @@ -13,6 +13,7 @@ class ModifiableValue { maxValue = 0; comment: string[]; battle: Battle; + dex: ModdedDex; pokemon: Pokemon; serverPokemon: ServerPokemon; itemName: string; @@ -22,14 +23,15 @@ class ModifiableValue { constructor(battle: Battle, pokemon: Pokemon, serverPokemon: ServerPokemon) { this.comment = []; this.battle = battle; + this.dex = this.battle.dex; this.pokemon = pokemon; this.serverPokemon = serverPokemon; - this.itemName = Dex.items.get(serverPokemon.item).name; + this.itemName = this.dex.items.get(serverPokemon.item).name; const ability = serverPokemon.ability || pokemon?.ability || serverPokemon.baseAbility; - this.abilityName = Dex.abilities.get(ability).name; - this.weatherName = battle.weather === 'snow' ? 'Snow' : Dex.moves.get(battle.weather).exists ? - Dex.moves.get(battle.weather).name : Dex.abilities.get(battle.weather).name; + this.abilityName = this.dex.abilities.get(ability).name; + this.weatherName = battle.weather === 'snow' ? 'Snow' : this.dex.moves.get(battle.weather).exists ? + this.dex.moves.get(battle.weather).name : this.dex.abilities.get(battle.weather).name; } reset(value = 0, isAccuracy?: boolean) { this.value = value; @@ -106,6 +108,8 @@ class ModifiableValue { if (name) this.comment.push(` (${this.round(factor)}× from ${name})`); this.value *= factor; if (!(name === 'Technician' && this.maxValue > 60)) this.maxValue *= factor; + if (this.battle.tier.includes('Super Staff Bros') && + !(name === 'Confirmed Town' && this.maxValue > 60)) this.maxValue *= factor; return true; } set(value: number, reason?: string) { @@ -139,9 +143,11 @@ class ModifiableValue { class BattleTooltips { battle: Battle; + dex: ModdedDex; constructor(battle: Battle) { this.battle = battle; + this.dex = this.battle.dex; } // tooltips @@ -268,18 +274,21 @@ class BattleTooltips { * cover up buttons above the hovered button. */ let ownHeight = !!elem.dataset.ownheight; + if (this.battle.id.includes('superstaffbros')) { + this.dex = Dex.mod('gen9ssb' as ID); + } let buf: string; switch (type) { case 'move': case 'zmove': case 'maxmove': { // move|MOVE|ACTIVEPOKEMON|[GMAXMOVE] - let move = this.battle.dex.moves.get(args[1]); + let move = this.dex.moves.get(args[1]); let teamIndex = parseInt(args[2], 10); let pokemon = this.battle.nearSide.active[ teamIndex + this.battle.pokemonControlled * Math.floor(this.battle.mySide.n / 2) ]; - let gmaxMove = args[3] ? this.battle.dex.moves.get(args[3]) : undefined; + let gmaxMove = args[3] ? this.dex.moves.get(args[3]) : undefined; if (!pokemon) return false; let serverPokemon = this.battle.myPokemon![teamIndex]; buf = this.showMoveTooltip(move, type, pokemon, serverPokemon, gmaxMove); @@ -523,10 +532,10 @@ class BattleTooltips { getMaxMoveFromType(type: TypeName, gmaxMove?: string | Move) { if (gmaxMove) { - gmaxMove = Dex.moves.get(gmaxMove); + if (typeof gmaxMove === 'string') gmaxMove = this.dex.moves.get(gmaxMove); if (type === gmaxMove.type) return gmaxMove; } - return Dex.moves.get(BattleTooltips.maxMoveTable[type]); + return this.dex.moves.get(BattleTooltips.maxMoveTable[type]); } showMoveTooltip(move: Move, isZOrMax: string, pokemon: Pokemon, serverPokemon: ServerPokemon, gmaxMove?: Move) { @@ -534,13 +543,16 @@ class BattleTooltips { let zEffect = ''; let foeActive = pokemon.side.foe.active; + if (this.battle.id.includes('superstaffbros')) { + this.dex = Dex.mod('gen9ssb' as ID); + } if (this.battle.gameType === 'freeforall') { foeActive = [...foeActive, ...pokemon.side.active].filter(active => active !== pokemon); } // TODO: move this somewhere it makes more sense if (pokemon.ability === '(suppressed)') serverPokemon.ability = '(suppressed)'; let ability = toID(serverPokemon.ability || pokemon.ability || serverPokemon.baseAbility); - let item = this.battle.dex.items.get(serverPokemon.item); + let item = this.dex.items.get(serverPokemon.item); let value = new ModifiableValue(this.battle, pokemon, serverPokemon); let [moveType, category] = this.getMoveType(move, value, gmaxMove || isZOrMax === 'maxmove'); @@ -548,7 +560,7 @@ class BattleTooltips { if (isZOrMax === 'zmove') { if (item.zMoveFrom === move.name) { - move = this.battle.dex.moves.get(item.zMove as string); + move = this.dex.moves.get(item.zMove as string); } else if (move.category === 'Status') { move = new Move(move.id, "", { ...move, @@ -557,28 +569,28 @@ class BattleTooltips { zEffect = this.getStatusZMoveEffect(move); } else { let moveName = BattleTooltips.zMoveTable[item.zMoveType as TypeName]; - let zMove = this.battle.dex.moves.get(moveName); + let zMove = this.dex.moves.get(moveName); let movePower = move.zMove!.basePower; // the different Hidden Power types don't have a Z power set, fall back on base move if (!movePower && move.id.startsWith('hiddenpower')) { - movePower = this.battle.dex.moves.get('hiddenpower').zMove!.basePower; + movePower = this.dex.moves.get('hiddenpower').zMove!.basePower; } if (move.id === 'weatherball') { switch (this.battle.weather) { case 'sunnyday': case 'desolateland': - zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Fire']); + zMove = this.dex.moves.get(BattleTooltips.zMoveTable['Fire']); break; case 'raindance': case 'primordialsea': - zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Water']); + zMove = this.dex.moves.get(BattleTooltips.zMoveTable['Water']); break; case 'sandstorm': - zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Rock']); + zMove = this.dex.moves.get(BattleTooltips.zMoveTable['Rock']); break; case 'hail': case 'snow': - zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Ice']); + zMove = this.dex.moves.get(BattleTooltips.zMoveTable['Ice']); break; } } @@ -591,7 +603,7 @@ class BattleTooltips { } } else if (isZOrMax === 'maxmove') { if (move.category === 'Status') { - move = this.battle.dex.moves.get('Max Guard'); + move = this.dex.moves.get('Max Guard'); } else { let maxMove = this.getMaxMoveFromType(moveType, gmaxMove); const basePower = ['gmaxdrumsolo', 'gmaxfireball', 'gmaxhydrosnipe'].includes(maxMove.id) ? @@ -671,7 +683,7 @@ class BattleTooltips { // In gen 3 it calls Swift, so it retains its normal typing. calls = 'Swift'; } - let calledMove = this.battle.dex.moves.get(calls); + let calledMove = this.dex.moves.get(calls); text += 'Calls ' + Dex.getTypeIcon(this.getMoveType(calledMove, value)[0]) + ' ' + calledMove.name; } @@ -871,10 +883,10 @@ class BattleTooltips { let itemEffect = ''; if (clientPokemon?.prevItem) { item = 'None'; - let prevItem = Dex.items.get(clientPokemon.prevItem).name; + let prevItem = this.dex.items.get(clientPokemon.prevItem).name; itemEffect += clientPokemon.prevItemEffect ? prevItem + ' was ' + clientPokemon.prevItemEffect : 'was ' + prevItem; } - if (serverPokemon.item) item = Dex.items.get(serverPokemon.item).name; + if (serverPokemon.item) item = this.dex.items.get(serverPokemon.item).name; if (itemEffect) itemEffect = ' (' + itemEffect + ')'; if (item) itemText = 'Item: ' + item + itemEffect; } else if (clientPokemon) { @@ -883,10 +895,10 @@ class BattleTooltips { if (clientPokemon.prevItem) { item = 'None'; if (itemEffect) itemEffect += '; '; - let prevItem = Dex.items.get(clientPokemon.prevItem).name; + let prevItem = this.dex.items.get(clientPokemon.prevItem).name; itemEffect += clientPokemon.prevItemEffect ? prevItem + ' was ' + clientPokemon.prevItemEffect : 'was ' + prevItem; } - if (pokemon.item) item = Dex.items.get(pokemon.item).name; + if (pokemon.item) item = this.dex.items.get(pokemon.item).name; if (itemEffect) itemEffect = ' (' + itemEffect + ')'; if (item) itemText = 'Item: ' + item + itemEffect; } @@ -909,7 +921,7 @@ class BattleTooltips { text += `

      `; const battlePokemon = clientPokemon || this.battle.findCorrespondingPokemon(pokemon); for (const moveid of serverPokemon.moves) { - const move = Dex.moves.get(moveid); + const move = this.dex.moves.get(moveid); let moveName = `• ${move.name}`; if (battlePokemon?.moveTrack) { for (const row of battlePokemon.moveTrack) { @@ -930,7 +942,7 @@ class BattleTooltips { } if (clientPokemon.moveTrack.filter(([moveName]) => { if (moveName.charAt(0) === '*') return false; - const move = this.battle.dex.moves.get(moveName); + const move = this.dex.moves.get(moveName); return !move.isZ && !move.isMax && move.name !== 'Mimic'; }).length > 4) { text += `(More than 4 moves is usually a sign of Illusion Zoroark/Zorua.) `; @@ -994,6 +1006,11 @@ class BattleTooltips { if (statName === 'def') sourceStatName = 'atk'; } stats[statName] = serverPokemon.stats[sourceStatName]; + // SSB + if (this.battle.tier.includes("Super Staff Bros") && clientPokemon?.volatiles['ok']) { + if (statName === 'spa') stats[statName] += Math.floor(stats.atk / 10); + if (statName === 'spe') stats[statName] += Math.floor(stats.atk * 9 / 10); + } if (!clientPokemon) continue; const clientStatName = clientPokemon.boosts.spc && (statName === 'spa' || statName === 'spd') ? 'spc' : statName; @@ -1046,10 +1063,10 @@ class BattleTooltips { item = '' as ID; } - const species = Dex.species.get(serverPokemon.speciesForme).baseSpecies; + const species = this.dex.species.get(serverPokemon.speciesForme).baseSpecies; const isTransform = clientPokemon?.volatiles.transform; const speciesName = isTransform && clientPokemon?.volatiles.formechange?.[1] && this.battle.gen <= 4 ? - this.battle.dex.species.get(clientPokemon.volatiles.formechange[1]).baseSpecies : species; + this.dex.species.get(clientPokemon.volatiles.formechange[1]).baseSpecies : species; let speedModifiers = []; @@ -1168,14 +1185,14 @@ class BattleTooltips { if (ability === 'marvelscale' && pokemon.status) { stats.def = Math.floor(stats.def * 1.5); } - const isNFE = this.battle.dex.species.get(serverPokemon.speciesForme).evos?.some(evo => { - const evoSpecies = this.battle.dex.species.get(evo); + const isNFE = this.dex.species.get(serverPokemon.speciesForme).evos?.some(evo => { + const evoSpecies = this.dex.species.get(evo); return !evoSpecies.isNonstandard || - evoSpecies.isNonstandard === this.battle.dex.species.get(serverPokemon.speciesForme)?.isNonstandard || + evoSpecies.isNonstandard === this.dex.species.get(serverPokemon.speciesForme)?.isNonstandard || // Pokemon with Hisui evolutions evoSpecies.isNonstandard === "Unobtainable"; }); - if (item === 'eviolite' && (isNFE || this.battle.dex.species.get(serverPokemon.speciesForme).id === 'dipplin')) { + if (item === 'eviolite' && (isNFE || this.dex.species.get(serverPokemon.speciesForme).id === 'dipplin')) { stats.def = Math.floor(stats.def * 1.5); stats.spd = Math.floor(stats.spd * 1.5); } @@ -1249,6 +1266,86 @@ class BattleTooltips { stats.spd = Math.floor(stats.spd * 0.75); } } + + // SSB + if (this.battle.tier.includes("Super Staff Bros")) { + if (ability === 'misspelled') { + stats.spa = Math.floor(stats.spa * 1.5); + } + if (ability === 'fortifyingfrost' && weather === 'snow') { + stats.spa = Math.floor(stats.spa * 1.5); + stats.spd = Math.floor(stats.spd * 1.5); + } + if (weather === 'deserteddunes' && this.pokemonHasType(pokemon, 'Rock')) { + stats.spd = Math.floor(stats.spd * 1.5); + } + if (pokemon.status && ability === 'fortifiedmetal') { + stats.atk = Math.floor(stats.atk * 1.5); + } + if (ability === 'grassyemperor' && this.battle.hasPseudoWeather('Grassy Terrain')) { + stats.atk = Math.floor(stats.atk * 1.3333); + } + if (ability === 'magicalmysterycharge' && this.battle.hasPseudoWeather('Electric Terrain')) { + stats.spd = Math.floor(stats.spd * 1.5); + } + if (ability === 'youkaiofthedusk' || ability === 'galeguard') { + stats.def *= 2; + } + if (ability === 'climatechange') { + if (weather === 'snow') { + stats.def = Math.floor(stats.def * 1.5); + stats.spd = Math.floor(stats.spd * 1.5); + } + if (weather === 'sunnyday' || weather === 'desolateland') stats.spa = Math.floor(stats.spa * 1.5); + } + if (item !== 'utilityumbrella' && ability === 'ridethesun' && + (weather === 'sunnyday' || weather === 'desolateland')) { + speedModifiers.push(2); + } + if (ability === 'soulsurfer' && this.battle.hasPseudoWeather('Electric Terrain')) { + speedModifiers.push(2); + } + if (item === 'eviolite' && this.dex.species.get(serverPokemon.speciesForme).id === 'pichuspikyeared') { + stats.def = Math.floor(stats.def * 1.5); + stats.spd = Math.floor(stats.spd * 1.5); + } + if (this.battle.abilityActive('quagofruin')) { + if (ability !== 'quagofruin') { + stats.def = Math.floor(stats.def * 0.85); + } + } + if (this.battle.abilityActive('clodofruin')) { + if (ability !== 'clodofruin') { + stats.atk = Math.floor(stats.atk * 0.85); + } + } + if (this.battle.abilityActive('blitzofruin')) { + if (ability !== 'blitzofruin') { + speedModifiers.push(0.75); + } + } + if (this.battle.hasPseudoWeather('Anfield Atmosphere') && ability === 'youllneverwalkalone') { + stats.atk = Math.floor(stats.atk * 1.25); + stats.def = Math.floor(stats.def * 1.25); + stats.spd = Math.floor(stats.spd * 1.25); + speedModifiers.push(1.25); + } + if (clientPokemon) { + if (clientPokemon.volatiles['boiled']) { + stats.spa = Math.floor(stats.spa * 1.5); + } + for (const statName of Dex.statNamesExceptHP) { + if (clientPokemon.volatiles['ultramystik']) { + if (statName === 'spe') { + speedModifiers.push(1.5); + } else { + stats[statName] = Math.floor(stats[statName] * 1.5); + } + } + } + } + } + const sideConditions = this.battle.mySide.sideConditions; if (sideConditions['tailwind']) { speedModifiers.push(2); @@ -1329,10 +1426,10 @@ class BattleTooltips { let maxpp; if (moveName.charAt(0) === '*') { // Transformed move - move = this.battle.dex.moves.get(moveName.substr(1)); + move = this.dex.moves.get(moveName.substr(1)); maxpp = 5; } else { - move = this.battle.dex.moves.get(moveName); + move = this.dex.moves.get(moveName); maxpp = (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5); if (this.battle.gen < 3) maxpp = Math.min(61, maxpp); } @@ -1370,7 +1467,7 @@ class BattleTooltips { if (baseSpe > 255) baseSpe = 255; } if (rules['Frantic Fusions Mod']) { - const fusionSpecies = this.battle.dex.species.get(pokemon.name); + const fusionSpecies = this.dex.species.get(pokemon.name); if (fusionSpecies.exists && fusionSpecies.name !== species.name) { baseSpe = baseSpe + tr(fusionSpecies.baseStats.spe / 4); if (baseSpe < 1) baseSpe = 1; @@ -1432,7 +1529,7 @@ class BattleTooltips { moveType = pokemonTypes[0]; } // Moves that require an item to change their type. - let item = Dex.items.get(value.itemName); + let item = this.dex.items.get(value.itemName); if (move.id === 'multiattack' && item.onMemory) { if (value.itemModify(0)) moveType = item.onMemory; } @@ -1558,6 +1655,54 @@ class BattleTooltips { const stats = this.calculateModifiedStats(pokemon, serverPokemon, true); if (stats.atk > stats.spa) category = 'Physical'; } + + // SSB + if (this.battle.tier.includes("Super Staff Bros")) { + if (allowTypeOverride && category !== "Status" && !move.isZ && !move.id.startsWith('hiddenpower')) { + if (value.abilityModify(0, 'Acetosa')) moveType = 'Grass'; + if (value.abilityModify(0, 'I Can Hear The Heart Beating As One') && moveType === 'Normal') moveType = 'Fairy'; + } + if (move.id === 'tsignore' || move.id === 'o') { + const stats = this.calculateModifiedStats(pokemon, serverPokemon, true); + if (stats.atk > stats.spa) category = 'Physical'; + } + if (move.id === 'tsignore' && pokemon.getSpeciesForme().startsWith('Meloetta') && + pokemon.terastallized) { + moveType = 'Stellar'; + } + if (move.id === 'weatherball' && value.weatherModify(0)) { + if (this.battle.weather === 'stormsurge') moveType = 'Water'; + if (this.battle.weather === 'deserteddunes') moveType = 'Rock'; + } + if (move.id === 'o' || move.id === 'worriednoises') { + moveType = pokemonTypes[0]; + } + if (move.id === 'dillydally') { + moveType = pokemonTypes[pokemonTypes.length - 1]; + } + if (move.id === 'magicalfocus') { + if (this.battle.turn % 3 === 1) { + moveType = 'Fire'; + } else if (this.battle.turn % 3 === 2) { + moveType = 'Electric'; + } else { + moveType = 'Ice'; + } + } + if (move.id === 'hydrostatics' && pokemon.terastallized) { + moveType = 'Water'; + } + if (move.id === 'asongoficeandfire' && pokemon.getSpeciesForme() === 'Volcarona') moveType = 'Ice'; + if (this.battle.abilityActive('dynamictyping')) { + moveType = '???'; + } + if (move.id === 'alting') { + moveType = '???'; + if (pokemon.shiny) { + category = 'Special'; + } + } + } return [moveType, category]; } @@ -1635,6 +1780,38 @@ class BattleTooltips { value.itemModify(1.1, "Wide Lens"); } + // SSB + if (this.battle.tier.includes("Super Staff Bros")) { + if (move.id === 'alting' && pokemon.shiny) { + value.set(100); + } + if (move.flags['wind'] && this.battle.weather === 'stormsurge') { + value.weatherModify(0, 'Storm Surge'); + } + if (value.tryAbility('Misspelled') && move.category === 'Special') { + accuracyModifiers.push(3277); + value.abilityModify(0.8, "Misspelled"); + } + if (value.tryAbility('Hydrostatic Positivity') && ['Electric', 'Water'].includes(move.type)) { + accuracyModifiers.push(5325); + value.abilityModify(1.3, "Hydrostatic Positivity"); + } + if (value.tryAbility('Hardcore Hustle')) { + for (let i = 1; i <= 5 && i <= pokemon.side.faintCounter; i++) { + if (pokemon.volatiles[`fallen${i}`]) { + value.abilityModify([1, 0.95, 0.90, 0.85, 0.80, 0.75][i], "Hardcore Hustle"); + } + } + } + if (value.tryAbility('See No Evil, Hear No Evil, Speak No Evil') && + pokemon.getSpeciesForme().includes('Wellspring')) { + value.abilityModify(0, 'See No Evil, Hear No Evil, Speak No Evil'); + } + value.abilityModify(0, 'Sure Hit Sorcery'); + value.abilityModify(0, 'Eyes of Eternity'); + if (!value.value) return value; + } + // Chaining modifiers let chain = 4096; for (const mod of accuracyModifiers) { @@ -1835,7 +2012,7 @@ class BattleTooltips { } // Moves which have base power changed due to items if (serverPokemon.item) { - let item = Dex.items.get(serverPokemon.item); + let item = this.dex.items.get(serverPokemon.item); if (move.id === 'fling' && item.fling) { value.itemModify(item.fling.basePower); } @@ -2049,6 +2226,88 @@ class BattleTooltips { value.set(0, 'no Terrain'); } + // SSB + if (this.battle.tier.includes("Super Staff Bros")) { + this.dex = Dex.mod('gen9ssb' as ID); + if (move.id === 'bodycount') { + value.set(50 + 50 * pokemon.side.faintCounter, + pokemon.side.faintCounter > 0 + ? `${pokemon.side.faintCounter} teammate${pokemon.side.faintCounter > 1 ? 's' : ''} KOed` + : undefined); + } + // Base power based on times hit + if (move.id === 'vengefulmood') { + value.set(Math.min(140, 60 + 20 * pokemon.timesAttacked), + pokemon.timesAttacked > 0 + ? `Hit ${pokemon.timesAttacked} time${pokemon.timesAttacked > 1 ? 's' : ''}` + : undefined); + } + if (move.id === 'alting' && pokemon.shiny) { + value.set(69, 'Shiny'); + } + if (move.id === 'darkmooncackle') { + let boostCount = 0; + for (const boost of Object.values(pokemon.boosts)) { + if (boost > 0) boostCount += boost; + } + value.set(30 + 20 * boostCount); + } + if (move.id === 'buildingcharacter' && target?.terastallized) { + value.modify(2, 'Terastallized target'); + } + if (move.id === 'mysticalbonfire' && target?.status) { + value.modify(2, 'Mystical Bonfire + status'); + } + if (move.id === 'adaptivebeam' && target) { + let boostCount = 0; + let targetBoostCount = 0; + for (const boost of Object.values(pokemon.boosts)) { + if (boost > 0) boostCount += boost; + } + for (const boost of Object.values(target.boosts)) { + if (boost > 0) targetBoostCount += boost; + } + if (targetBoostCount >= boostCount) value.modify(2, "Target has more boosts"); + } + if (value.value <= 60) { + value.abilityModify(1.5, "Confirmed Town"); + } + if (move.category !== 'Status' && allowTypeOverride && !move.isZ && + !move.isMax && !move.id.startsWith('hiddenpower')) { + if (moveType === 'Normal') value.abilityModify(this.battle.gen > 6 ? 1.2 : 1.3, "I Can Hear The Heart Beating As One"); + value.abilityModify(this.battle.gen > 6 ? 1.2 : 1.3, "Acetosa"); + } + if (move.flags['sound']) { + value.abilityModify(1.5, "Cacophony"); + } + if (move.flags['punch']) { + value.abilityModify(1.3, "Harambe Hit"); + } + if (move.flags['slicing']) { + value.abilityModify(1.5, "I Can Hear The Heart Beating As One"); + } + if (move.priority > 0) { + value.abilityModify(2, "Full Bloom"); + } + if (move.recoil || move.hasCrashDamage) { + value.abilityModify(1.2, 'Hogwash'); + if (pokemon.name === "Billo") { + value.modify(1.2); + } + } + if (target?.gender === "M" && pokemon.getSpeciesForme().includes("Hearthflame")) { + value.abilityModify(1.3, 'See No Evil, Hear No Evil, Speak No Evil'); + } + for (let i = 1; i <= 5 && i <= pokemon.side.faintCounter; i++) { + if (pokemon.volatiles[`fallen${i}`]) { + value.abilityModify([1, 1.15, 1.3, 1.45, 1.6, 1.75][i], "Hardcore Hustle"); + } + } + let timeDilationBPMod = 1 + (0.1 * Math.floor(this.battle.turn / 10)); + if (timeDilationBPMod > 2) timeDilationBPMod = 2; + value.abilityModify(timeDilationBPMod, "Time Dilation"); + } + return value; } @@ -2105,13 +2364,13 @@ class BattleTooltips { 'Water Pledge', ]; getItemBoost(move: Move, value: ModifiableValue, moveType: TypeName) { - let item = this.battle.dex.items.get(value.serverPokemon.item); + let item = this.dex.items.get(value.serverPokemon.item); let itemName = item.name; let moveName = move.name; - let species = this.battle.dex.species.get(value.serverPokemon.speciesForme); + let species = this.dex.species.get(value.serverPokemon.speciesForme); let isTransform = value.pokemon.volatiles.transform; let speciesName = isTransform && value.pokemon.volatiles.formechange?.[1] && this.battle.gen <= 4 ? - this.battle.dex.species.get(value.pokemon.volatiles.formechange[1]).baseSpecies : species.baseSpecies; + this.dex.species.get(value.pokemon.volatiles.formechange[1]).baseSpecies : species.baseSpecies; // Plates if (item.onPlate === moveType && !item.zMove) { @@ -2168,7 +2427,7 @@ class BattleTooltips { } getPokemonTypes(pokemon: Pokemon | ServerPokemon, preterastallized = false): ReadonlyArray { if (!(pokemon as Pokemon).getTypes) { - return this.battle.dex.species.get(pokemon.speciesForme).types; + return this.dex.species.get(pokemon.speciesForme).types; } return (pokemon as Pokemon).getTypeList(undefined, preterastallized); @@ -2182,13 +2441,13 @@ class BattleTooltips { } getAllyAbility(ally: Pokemon) { // this will only be available if the ability announced itself in some way - let allyAbility = Dex.abilities.get(ally.ability).name; + let allyAbility = this.dex.abilities.get(ally.ability).name; // otherwise fall back on the original set data sent from the server if (!allyAbility) { if (this.battle.myAllyPokemon) { // multi battle ally - allyAbility = Dex.abilities.get(this.battle.myAllyPokemon[ally.slot].ability).name; + allyAbility = this.dex.abilities.get(this.battle.myAllyPokemon[ally.slot].ability || '').name; } else if (this.battle.myPokemon) { - allyAbility = Dex.abilities.get(this.battle.myPokemon[ally.slot].ability).name; + allyAbility = this.dex.abilities.get(this.battle.myPokemon[ally.slot].ability || '').name; } } return allyAbility; @@ -2205,14 +2464,14 @@ class BattleTooltips { } } else { const speciesForme = clientPokemon.getSpeciesForme() || serverPokemon?.speciesForme || ''; - const species = this.battle.dex.species.get(speciesForme); + const species = this.dex.species.get(speciesForme); if (species.exists && species.abilities) { abilityData.possibilities = [species.abilities['0']]; if (species.abilities['1']) abilityData.possibilities.push(species.abilities['1']); if (species.abilities['H']) abilityData.possibilities.push(species.abilities['H']); if (species.abilities['S']) abilityData.possibilities.push(species.abilities['S']); if (this.battle.rules['Frantic Fusions Mod']) { - const fusionSpecies = this.battle.dex.species.get(clientPokemon.name); + const fusionSpecies = this.dex.species.get(clientPokemon.name); if (fusionSpecies.exists && fusionSpecies.name !== species.name) { abilityData.possibilities = Array.from( new Set(abilityData.possibilities.concat(Object.values(fusionSpecies.abilities))) @@ -2241,12 +2500,12 @@ class BattleTooltips { if (!isActive) { // for switch tooltips, only show the original ability const ability = abilityData.baseAbility || abilityData.ability; - if (ability) text = 'Ability: ' + Dex.abilities.get(ability).name; + if (ability) text = 'Ability: ' + this.dex.abilities.get(ability).name; } else { if (abilityData.ability) { - const abilityName = Dex.abilities.get(abilityData.ability).name; + const abilityName = this.dex.abilities.get(abilityData.ability).name; text = 'Ability: ' + abilityName; - const baseAbilityName = Dex.abilities.get(abilityData.baseAbility).name; + const baseAbilityName = this.dex.abilities.get(abilityData.baseAbility).name; if (baseAbilityName && baseAbilityName !== abilityName) text += ' (base: ' + baseAbilityName + ')'; } } diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index d5c67d86ae..c6679f9f4f 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -3381,6 +3381,9 @@ export class Battle { if (this.tier.includes(`Let's Go`)) { this.dex = Dex.mod('gen7letsgo' as ID); } + if (this.tier.includes(`Super Staff Bros`)) { + this.dex = Dex.mod('gen9ssb' as ID); + } this.log(args); break; } @@ -3695,6 +3698,21 @@ export class Battle { this.scene.setControlsHTML(BattleLog.sanitizeHTML(args[1])); break; } + case 'custom': { + // Style is always |custom|-subprotocol|pokemon|additional info + if (args[1] === '-endterastallize') { + let poke = this.getPokemon(args[2])!; + poke.removeVolatile('terastallize' as ID); + poke.teraType = ''; + poke.terastallized = ''; + poke.details = poke.details.replace(/, tera:[a-z]+/i, ''); + poke.searchid = poke.searchid.replace(/, tera:[a-z]+/i, ''); + this.scene.animTransform(poke); + this.scene.resetStatbar(poke); + this.log(args, kwArgs); + } + break; + } default: { this.log(args, kwArgs, preempt); break; From 3e518b34c1a4591578ec1cf37ad51316d63e0277 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Mon, 6 May 2024 17:25:29 -0400 Subject: [PATCH 669/770] Fix past gen tooltips (#2247) --- .../src/battle-animations.ts | 1 - .../src/battle-tooltips.ts | 117 ++++++++---------- play.pokemonshowdown.com/src/battle.ts | 2 +- 3 files changed, 54 insertions(+), 66 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index 3cd37baca4..31087b3da5 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -122,7 +122,6 @@ export class BattleScene implements BattleSceneStub { } this.numericId = numericId; this.tooltips = new BattleTooltips(battle); - if (this.battle.id.includes('superstaffbros')) this.tooltips.dex = Dex.mod('gen9ssb' as ID); this.tooltips.listen($frame[0]); this.preloadEffects(); diff --git a/play.pokemonshowdown.com/src/battle-tooltips.ts b/play.pokemonshowdown.com/src/battle-tooltips.ts index 1805628fac..2b6df5c994 100644 --- a/play.pokemonshowdown.com/src/battle-tooltips.ts +++ b/play.pokemonshowdown.com/src/battle-tooltips.ts @@ -13,7 +13,6 @@ class ModifiableValue { maxValue = 0; comment: string[]; battle: Battle; - dex: ModdedDex; pokemon: Pokemon; serverPokemon: ServerPokemon; itemName: string; @@ -23,15 +22,14 @@ class ModifiableValue { constructor(battle: Battle, pokemon: Pokemon, serverPokemon: ServerPokemon) { this.comment = []; this.battle = battle; - this.dex = this.battle.dex; this.pokemon = pokemon; this.serverPokemon = serverPokemon; - this.itemName = this.dex.items.get(serverPokemon.item).name; + this.itemName = this.battle.dex.items.get(serverPokemon.item).name; const ability = serverPokemon.ability || pokemon?.ability || serverPokemon.baseAbility; - this.abilityName = this.dex.abilities.get(ability).name; - this.weatherName = battle.weather === 'snow' ? 'Snow' : this.dex.moves.get(battle.weather).exists ? - this.dex.moves.get(battle.weather).name : this.dex.abilities.get(battle.weather).name; + this.abilityName = this.battle.dex.abilities.get(ability).name; + this.weatherName = battle.weather === 'snow' ? 'Snow' : this.battle.dex.moves.get(battle.weather).exists ? + this.battle.dex.moves.get(battle.weather).name : this.battle.dex.abilities.get(battle.weather).name; } reset(value = 0, isAccuracy?: boolean) { this.value = value; @@ -143,11 +141,9 @@ class ModifiableValue { class BattleTooltips { battle: Battle; - dex: ModdedDex; constructor(battle: Battle) { this.battle = battle; - this.dex = this.battle.dex; } // tooltips @@ -274,21 +270,18 @@ class BattleTooltips { * cover up buttons above the hovered button. */ let ownHeight = !!elem.dataset.ownheight; - if (this.battle.id.includes('superstaffbros')) { - this.dex = Dex.mod('gen9ssb' as ID); - } let buf: string; switch (type) { case 'move': case 'zmove': case 'maxmove': { // move|MOVE|ACTIVEPOKEMON|[GMAXMOVE] - let move = this.dex.moves.get(args[1]); + let move = this.battle.dex.moves.get(args[1]); let teamIndex = parseInt(args[2], 10); let pokemon = this.battle.nearSide.active[ teamIndex + this.battle.pokemonControlled * Math.floor(this.battle.mySide.n / 2) ]; - let gmaxMove = args[3] ? this.dex.moves.get(args[3]) : undefined; + let gmaxMove = args[3] ? this.battle.dex.moves.get(args[3]) : undefined; if (!pokemon) return false; let serverPokemon = this.battle.myPokemon![teamIndex]; buf = this.showMoveTooltip(move, type, pokemon, serverPokemon, gmaxMove); @@ -532,10 +525,10 @@ class BattleTooltips { getMaxMoveFromType(type: TypeName, gmaxMove?: string | Move) { if (gmaxMove) { - if (typeof gmaxMove === 'string') gmaxMove = this.dex.moves.get(gmaxMove); + if (typeof gmaxMove === 'string') gmaxMove = this.battle.dex.moves.get(gmaxMove); if (type === gmaxMove.type) return gmaxMove; } - return this.dex.moves.get(BattleTooltips.maxMoveTable[type]); + return this.battle.dex.moves.get(BattleTooltips.maxMoveTable[type]); } showMoveTooltip(move: Move, isZOrMax: string, pokemon: Pokemon, serverPokemon: ServerPokemon, gmaxMove?: Move) { @@ -543,16 +536,13 @@ class BattleTooltips { let zEffect = ''; let foeActive = pokemon.side.foe.active; - if (this.battle.id.includes('superstaffbros')) { - this.dex = Dex.mod('gen9ssb' as ID); - } if (this.battle.gameType === 'freeforall') { foeActive = [...foeActive, ...pokemon.side.active].filter(active => active !== pokemon); } // TODO: move this somewhere it makes more sense if (pokemon.ability === '(suppressed)') serverPokemon.ability = '(suppressed)'; let ability = toID(serverPokemon.ability || pokemon.ability || serverPokemon.baseAbility); - let item = this.dex.items.get(serverPokemon.item); + let item = this.battle.dex.items.get(serverPokemon.item); let value = new ModifiableValue(this.battle, pokemon, serverPokemon); let [moveType, category] = this.getMoveType(move, value, gmaxMove || isZOrMax === 'maxmove'); @@ -560,7 +550,7 @@ class BattleTooltips { if (isZOrMax === 'zmove') { if (item.zMoveFrom === move.name) { - move = this.dex.moves.get(item.zMove as string); + move = this.battle.dex.moves.get(item.zMove as string); } else if (move.category === 'Status') { move = new Move(move.id, "", { ...move, @@ -569,28 +559,28 @@ class BattleTooltips { zEffect = this.getStatusZMoveEffect(move); } else { let moveName = BattleTooltips.zMoveTable[item.zMoveType as TypeName]; - let zMove = this.dex.moves.get(moveName); + let zMove = this.battle.dex.moves.get(moveName); let movePower = move.zMove!.basePower; // the different Hidden Power types don't have a Z power set, fall back on base move if (!movePower && move.id.startsWith('hiddenpower')) { - movePower = this.dex.moves.get('hiddenpower').zMove!.basePower; + movePower = this.battle.dex.moves.get('hiddenpower').zMove!.basePower; } if (move.id === 'weatherball') { switch (this.battle.weather) { case 'sunnyday': case 'desolateland': - zMove = this.dex.moves.get(BattleTooltips.zMoveTable['Fire']); + zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Fire']); break; case 'raindance': case 'primordialsea': - zMove = this.dex.moves.get(BattleTooltips.zMoveTable['Water']); + zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Water']); break; case 'sandstorm': - zMove = this.dex.moves.get(BattleTooltips.zMoveTable['Rock']); + zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Rock']); break; case 'hail': case 'snow': - zMove = this.dex.moves.get(BattleTooltips.zMoveTable['Ice']); + zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Ice']); break; } } @@ -603,7 +593,7 @@ class BattleTooltips { } } else if (isZOrMax === 'maxmove') { if (move.category === 'Status') { - move = this.dex.moves.get('Max Guard'); + move = this.battle.dex.moves.get('Max Guard'); } else { let maxMove = this.getMaxMoveFromType(moveType, gmaxMove); const basePower = ['gmaxdrumsolo', 'gmaxfireball', 'gmaxhydrosnipe'].includes(maxMove.id) ? @@ -683,7 +673,7 @@ class BattleTooltips { // In gen 3 it calls Swift, so it retains its normal typing. calls = 'Swift'; } - let calledMove = this.dex.moves.get(calls); + let calledMove = this.battle.dex.moves.get(calls); text += 'Calls ' + Dex.getTypeIcon(this.getMoveType(calledMove, value)[0]) + ' ' + calledMove.name; } @@ -883,10 +873,10 @@ class BattleTooltips { let itemEffect = ''; if (clientPokemon?.prevItem) { item = 'None'; - let prevItem = this.dex.items.get(clientPokemon.prevItem).name; + let prevItem = this.battle.dex.items.get(clientPokemon.prevItem).name; itemEffect += clientPokemon.prevItemEffect ? prevItem + ' was ' + clientPokemon.prevItemEffect : 'was ' + prevItem; } - if (serverPokemon.item) item = this.dex.items.get(serverPokemon.item).name; + if (serverPokemon.item) item = this.battle.dex.items.get(serverPokemon.item).name; if (itemEffect) itemEffect = ' (' + itemEffect + ')'; if (item) itemText = 'Item: ' + item + itemEffect; } else if (clientPokemon) { @@ -895,10 +885,10 @@ class BattleTooltips { if (clientPokemon.prevItem) { item = 'None'; if (itemEffect) itemEffect += '; '; - let prevItem = this.dex.items.get(clientPokemon.prevItem).name; + let prevItem = this.battle.dex.items.get(clientPokemon.prevItem).name; itemEffect += clientPokemon.prevItemEffect ? prevItem + ' was ' + clientPokemon.prevItemEffect : 'was ' + prevItem; } - if (pokemon.item) item = this.dex.items.get(pokemon.item).name; + if (pokemon.item) item = this.battle.dex.items.get(pokemon.item).name; if (itemEffect) itemEffect = ' (' + itemEffect + ')'; if (item) itemText = 'Item: ' + item + itemEffect; } @@ -921,7 +911,7 @@ class BattleTooltips { text += `

      `; const battlePokemon = clientPokemon || this.battle.findCorrespondingPokemon(pokemon); for (const moveid of serverPokemon.moves) { - const move = this.dex.moves.get(moveid); + const move = this.battle.dex.moves.get(moveid); let moveName = `• ${move.name}`; if (battlePokemon?.moveTrack) { for (const row of battlePokemon.moveTrack) { @@ -942,7 +932,7 @@ class BattleTooltips { } if (clientPokemon.moveTrack.filter(([moveName]) => { if (moveName.charAt(0) === '*') return false; - const move = this.dex.moves.get(moveName); + const move = this.battle.dex.moves.get(moveName); return !move.isZ && !move.isMax && move.name !== 'Mimic'; }).length > 4) { text += `(More than 4 moves is usually a sign of Illusion Zoroark/Zorua.) `; @@ -1007,7 +997,7 @@ class BattleTooltips { } stats[statName] = serverPokemon.stats[sourceStatName]; // SSB - if (this.battle.tier.includes("Super Staff Bros") && clientPokemon?.volatiles['ok']) { + if (this.battle.tier.includes('Super Staff Bros') && clientPokemon?.volatiles['ok']) { if (statName === 'spa') stats[statName] += Math.floor(stats.atk / 10); if (statName === 'spe') stats[statName] += Math.floor(stats.atk * 9 / 10); } @@ -1063,10 +1053,10 @@ class BattleTooltips { item = '' as ID; } - const species = this.dex.species.get(serverPokemon.speciesForme).baseSpecies; + const species = this.battle.dex.species.get(serverPokemon.speciesForme).baseSpecies; const isTransform = clientPokemon?.volatiles.transform; const speciesName = isTransform && clientPokemon?.volatiles.formechange?.[1] && this.battle.gen <= 4 ? - this.dex.species.get(clientPokemon.volatiles.formechange[1]).baseSpecies : species; + this.battle.dex.species.get(clientPokemon.volatiles.formechange[1]).baseSpecies : species; let speedModifiers = []; @@ -1185,14 +1175,14 @@ class BattleTooltips { if (ability === 'marvelscale' && pokemon.status) { stats.def = Math.floor(stats.def * 1.5); } - const isNFE = this.dex.species.get(serverPokemon.speciesForme).evos?.some(evo => { - const evoSpecies = this.dex.species.get(evo); + const isNFE = this.battle.dex.species.get(serverPokemon.speciesForme).evos?.some(evo => { + const evoSpecies = this.battle.dex.species.get(evo); return !evoSpecies.isNonstandard || - evoSpecies.isNonstandard === this.dex.species.get(serverPokemon.speciesForme)?.isNonstandard || + evoSpecies.isNonstandard === this.battle.dex.species.get(serverPokemon.speciesForme)?.isNonstandard || // Pokemon with Hisui evolutions evoSpecies.isNonstandard === "Unobtainable"; }); - if (item === 'eviolite' && (isNFE || this.dex.species.get(serverPokemon.speciesForme).id === 'dipplin')) { + if (item === 'eviolite' && (isNFE || this.battle.dex.species.get(serverPokemon.speciesForme).id === 'dipplin')) { stats.def = Math.floor(stats.def * 1.5); stats.spd = Math.floor(stats.spd * 1.5); } @@ -1268,7 +1258,7 @@ class BattleTooltips { } // SSB - if (this.battle.tier.includes("Super Staff Bros")) { + if (this.battle.tier.includes('Super Staff Bros')) { if (ability === 'misspelled') { stats.spa = Math.floor(stats.spa * 1.5); } @@ -1305,7 +1295,7 @@ class BattleTooltips { if (ability === 'soulsurfer' && this.battle.hasPseudoWeather('Electric Terrain')) { speedModifiers.push(2); } - if (item === 'eviolite' && this.dex.species.get(serverPokemon.speciesForme).id === 'pichuspikyeared') { + if (item === 'eviolite' && this.battle.dex.species.get(serverPokemon.speciesForme).id === 'pichuspikyeared') { stats.def = Math.floor(stats.def * 1.5); stats.spd = Math.floor(stats.spd * 1.5); } @@ -1426,10 +1416,10 @@ class BattleTooltips { let maxpp; if (moveName.charAt(0) === '*') { // Transformed move - move = this.dex.moves.get(moveName.substr(1)); + move = this.battle.dex.moves.get(moveName.substr(1)); maxpp = 5; } else { - move = this.dex.moves.get(moveName); + move = this.battle.dex.moves.get(moveName); maxpp = (move.pp === 1 || move.noPPBoosts ? move.pp : move.pp * 8 / 5); if (this.battle.gen < 3) maxpp = Math.min(61, maxpp); } @@ -1467,7 +1457,7 @@ class BattleTooltips { if (baseSpe > 255) baseSpe = 255; } if (rules['Frantic Fusions Mod']) { - const fusionSpecies = this.dex.species.get(pokemon.name); + const fusionSpecies = this.battle.dex.species.get(pokemon.name); if (fusionSpecies.exists && fusionSpecies.name !== species.name) { baseSpe = baseSpe + tr(fusionSpecies.baseStats.spe / 4); if (baseSpe < 1) baseSpe = 1; @@ -1529,7 +1519,7 @@ class BattleTooltips { moveType = pokemonTypes[0]; } // Moves that require an item to change their type. - let item = this.dex.items.get(value.itemName); + let item = this.battle.dex.items.get(value.itemName); if (move.id === 'multiattack' && item.onMemory) { if (value.itemModify(0)) moveType = item.onMemory; } @@ -1657,7 +1647,7 @@ class BattleTooltips { } // SSB - if (this.battle.tier.includes("Super Staff Bros")) { + if (this.battle.tier.includes('Super Staff Bros')) { if (allowTypeOverride && category !== "Status" && !move.isZ && !move.id.startsWith('hiddenpower')) { if (value.abilityModify(0, 'Acetosa')) moveType = 'Grass'; if (value.abilityModify(0, 'I Can Hear The Heart Beating As One') && moveType === 'Normal') moveType = 'Fairy'; @@ -1781,7 +1771,7 @@ class BattleTooltips { } // SSB - if (this.battle.tier.includes("Super Staff Bros")) { + if (this.battle.tier.includes('Super Staff Bros')) { if (move.id === 'alting' && pokemon.shiny) { value.set(100); } @@ -2012,7 +2002,7 @@ class BattleTooltips { } // Moves which have base power changed due to items if (serverPokemon.item) { - let item = this.dex.items.get(serverPokemon.item); + let item = this.battle.dex.items.get(serverPokemon.item); if (move.id === 'fling' && item.fling) { value.itemModify(item.fling.basePower); } @@ -2227,8 +2217,7 @@ class BattleTooltips { } // SSB - if (this.battle.tier.includes("Super Staff Bros")) { - this.dex = Dex.mod('gen9ssb' as ID); + if (this.battle.tier.includes('Super Staff Bros')) { if (move.id === 'bodycount') { value.set(50 + 50 * pokemon.side.faintCounter, pokemon.side.faintCounter > 0 @@ -2364,13 +2353,13 @@ class BattleTooltips { 'Water Pledge', ]; getItemBoost(move: Move, value: ModifiableValue, moveType: TypeName) { - let item = this.dex.items.get(value.serverPokemon.item); + let item = this.battle.dex.items.get(value.serverPokemon.item); let itemName = item.name; let moveName = move.name; - let species = this.dex.species.get(value.serverPokemon.speciesForme); + let species = this.battle.dex.species.get(value.serverPokemon.speciesForme); let isTransform = value.pokemon.volatiles.transform; let speciesName = isTransform && value.pokemon.volatiles.formechange?.[1] && this.battle.gen <= 4 ? - this.dex.species.get(value.pokemon.volatiles.formechange[1]).baseSpecies : species.baseSpecies; + this.battle.dex.species.get(value.pokemon.volatiles.formechange[1]).baseSpecies : species.baseSpecies; // Plates if (item.onPlate === moveType && !item.zMove) { @@ -2427,7 +2416,7 @@ class BattleTooltips { } getPokemonTypes(pokemon: Pokemon | ServerPokemon, preterastallized = false): ReadonlyArray { if (!(pokemon as Pokemon).getTypes) { - return this.dex.species.get(pokemon.speciesForme).types; + return this.battle.dex.species.get(pokemon.speciesForme).types; } return (pokemon as Pokemon).getTypeList(undefined, preterastallized); @@ -2441,13 +2430,13 @@ class BattleTooltips { } getAllyAbility(ally: Pokemon) { // this will only be available if the ability announced itself in some way - let allyAbility = this.dex.abilities.get(ally.ability).name; + let allyAbility = this.battle.dex.abilities.get(ally.ability).name; // otherwise fall back on the original set data sent from the server if (!allyAbility) { if (this.battle.myAllyPokemon) { // multi battle ally - allyAbility = this.dex.abilities.get(this.battle.myAllyPokemon[ally.slot].ability || '').name; + allyAbility = this.battle.dex.abilities.get(this.battle.myAllyPokemon[ally.slot].ability || '').name; } else if (this.battle.myPokemon) { - allyAbility = this.dex.abilities.get(this.battle.myPokemon[ally.slot].ability || '').name; + allyAbility = this.battle.dex.abilities.get(this.battle.myPokemon[ally.slot].ability || '').name; } } return allyAbility; @@ -2464,14 +2453,14 @@ class BattleTooltips { } } else { const speciesForme = clientPokemon.getSpeciesForme() || serverPokemon?.speciesForme || ''; - const species = this.dex.species.get(speciesForme); + const species = this.battle.dex.species.get(speciesForme); if (species.exists && species.abilities) { abilityData.possibilities = [species.abilities['0']]; if (species.abilities['1']) abilityData.possibilities.push(species.abilities['1']); if (species.abilities['H']) abilityData.possibilities.push(species.abilities['H']); if (species.abilities['S']) abilityData.possibilities.push(species.abilities['S']); if (this.battle.rules['Frantic Fusions Mod']) { - const fusionSpecies = this.dex.species.get(clientPokemon.name); + const fusionSpecies = this.battle.dex.species.get(clientPokemon.name); if (fusionSpecies.exists && fusionSpecies.name !== species.name) { abilityData.possibilities = Array.from( new Set(abilityData.possibilities.concat(Object.values(fusionSpecies.abilities))) @@ -2500,12 +2489,12 @@ class BattleTooltips { if (!isActive) { // for switch tooltips, only show the original ability const ability = abilityData.baseAbility || abilityData.ability; - if (ability) text = 'Ability: ' + this.dex.abilities.get(ability).name; + if (ability) text = 'Ability: ' + this.battle.dex.abilities.get(ability).name; } else { if (abilityData.ability) { - const abilityName = this.dex.abilities.get(abilityData.ability).name; + const abilityName = this.battle.dex.abilities.get(abilityData.ability).name; text = 'Ability: ' + abilityName; - const baseAbilityName = this.dex.abilities.get(abilityData.baseAbility).name; + const baseAbilityName = this.battle.dex.abilities.get(abilityData.baseAbility).name; if (baseAbilityName && baseAbilityName !== abilityName) text += ' (base: ' + baseAbilityName + ')'; } } diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index c6679f9f4f..97d31b19d4 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -3381,7 +3381,7 @@ export class Battle { if (this.tier.includes(`Let's Go`)) { this.dex = Dex.mod('gen7letsgo' as ID); } - if (this.tier.includes(`Super Staff Bros`)) { + if (this.tier.includes('Super Staff Bros')) { this.dex = Dex.mod('gen9ssb' as ID); } this.log(args); From b399117bd04c8c658c93315c97231a0fc38279bf Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sun, 19 May 2024 11:35:59 -0600 Subject: [PATCH 670/770] CAP: Add Chuggalong minisprite index --- play.pokemonshowdown.com/src/battle-dex-data.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/play.pokemonshowdown.com/src/battle-dex-data.ts b/play.pokemonshowdown.com/src/battle-dex-data.ts index 23a17a940f..4d3dbe5b23 100644 --- a/play.pokemonshowdown.com/src/battle-dex-data.ts +++ b/play.pokemonshowdown.com/src/battle-dex-data.ts @@ -620,6 +620,7 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { ababo: 1512 + 71, scattervein: 1512 + 72, cresceidon: 1512 + 73, + chuggalong: 1512 + 74, }; const BattlePokemonIconIndexesLeft: {[id: string]: number} = { From bc98615e817624112db11cb47a9a35937ad67e62 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sun, 19 May 2024 14:58:37 -0600 Subject: [PATCH 671/770] SSB: Client-side balance patch changes (#2250) * SSB: Client-side balance patch changes * more changes * oops --- .../src/battle-tooltips.ts | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-tooltips.ts b/play.pokemonshowdown.com/src/battle-tooltips.ts index 2b6df5c994..792ca2ee05 100644 --- a/play.pokemonshowdown.com/src/battle-tooltips.ts +++ b/play.pokemonshowdown.com/src/battle-tooltips.ts @@ -996,11 +996,6 @@ class BattleTooltips { if (statName === 'def') sourceStatName = 'atk'; } stats[statName] = serverPokemon.stats[sourceStatName]; - // SSB - if (this.battle.tier.includes('Super Staff Bros') && clientPokemon?.volatiles['ok']) { - if (statName === 'spa') stats[statName] += Math.floor(stats.atk / 10); - if (statName === 'spe') stats[statName] += Math.floor(stats.atk * 9 / 10); - } if (!clientPokemon) continue; const clientStatName = clientPokemon.boosts.spc && (statName === 'spa' || statName === 'spd') ? 'spc' : statName; @@ -1259,6 +1254,9 @@ class BattleTooltips { // SSB if (this.battle.tier.includes('Super Staff Bros')) { + if (pokemon.name === 'Felucia') { + speedModifiers.push(1.5); + } if (ability === 'misspelled') { stats.spa = Math.floor(stats.spa * 1.5); } @@ -1327,9 +1325,9 @@ class BattleTooltips { for (const statName of Dex.statNamesExceptHP) { if (clientPokemon.volatiles['ultramystik']) { if (statName === 'spe') { - speedModifiers.push(1.5); + speedModifiers.push(1.3); } else { - stats[statName] = Math.floor(stats[statName] * 1.5); + stats[statName] = Math.floor(stats[statName] * 1.3); } } } @@ -2245,18 +2243,10 @@ class BattleTooltips { value.modify(2, 'Terastallized target'); } if (move.id === 'mysticalbonfire' && target?.status) { - value.modify(2, 'Mystical Bonfire + status'); + value.modify(1.5, 'Mystical Bonfire + status'); } - if (move.id === 'adaptivebeam' && target) { - let boostCount = 0; - let targetBoostCount = 0; - for (const boost of Object.values(pokemon.boosts)) { - if (boost > 0) boostCount += boost; - } - for (const boost of Object.values(target.boosts)) { - if (boost > 0) targetBoostCount += boost; - } - if (targetBoostCount >= boostCount) value.modify(2, "Target has more boosts"); + if (move.id === 'adaptivebeam' && target && Object.values(target.boosts).some(x => x > 0)) { + value.set(0, "Target has more boosts"); } if (value.value <= 60) { value.abilityModify(1.5, "Confirmed Town"); @@ -2266,11 +2256,8 @@ class BattleTooltips { if (moveType === 'Normal') value.abilityModify(this.battle.gen > 6 ? 1.2 : 1.3, "I Can Hear The Heart Beating As One"); value.abilityModify(this.battle.gen > 6 ? 1.2 : 1.3, "Acetosa"); } - if (move.flags['sound']) { - value.abilityModify(1.5, "Cacophony"); - } if (move.flags['punch']) { - value.abilityModify(1.3, "Harambe Hit"); + value.abilityModify(1.5, "Harambe Hit"); } if (move.flags['slicing']) { value.abilityModify(1.5, "I Can Hear The Heart Beating As One"); From 8acf7c076bf0e34dacdd71469e8f1e15f0970a63 Mon Sep 17 00:00:00 2001 From: Leonard Craft III Date: Mon, 27 May 2024 17:02:27 -0500 Subject: [PATCH 672/770] Mark more evolution items as bad --- build-tools/build-indexes | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index ab08227c74..008bc61b7e 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -766,6 +766,12 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); case 'chippedpot': case 'crackedpot': case 'galaricawreath': + case 'auspiciousarmor': + case 'maliciousarmor': + case 'masterpieceteacup': + case 'metalalloy': + case 'unremarkableteacup': + case 'bignugget': badItems.push(id); break; // outclassed items From bb5f187cdcbabd8857316f7f5cdf53794a7f3523 Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 20 Jun 2024 00:43:13 -0400 Subject: [PATCH 673/770] Fix tooltips getting cleared when using switch moves (#2251) --- play.pokemonshowdown.com/src/battle.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index 97d31b19d4..a5595832f1 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -3362,6 +3362,10 @@ export class Battle { case 'upkeep': { this.usesUpkeep = true; this.updateTurnCounters(); + // Prevents getSwitchedPokemon from skipping over a Pokemon that switched out mid turn (e.g. U-turn) + for (const side of this.sides) { + side.lastPokemon = null; + } break; } case 'turn': { From 442d576c3198c5dd48715f39a3c1ba8c2528462a Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Thu, 20 Jun 2024 00:44:15 -0400 Subject: [PATCH 674/770] Override Fling and Natural Gift data for items in past gens (#2252) --- build-tools/build-indexes | 25 ++++++++++++++++++---- play.pokemonshowdown.com/src/battle-dex.ts | 15 ++++++++----- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 008bc61b7e..cbec9f3f61 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -1077,6 +1077,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const overrideSpeciesKeys = ['abilities', 'baseStats', 'cosmeticFormes', 'isNonstandard', 'requiredItems', 'types', 'unreleasedHidden']; const overrideMoveKeys = ['accuracy', 'basePower', 'category', 'desc', 'flags', 'isNonstandard', 'noSketch', 'pp', 'priority', 'shortDesc', 'target', 'type']; const overrideAbilityKeys = ['desc', 'flags', 'isNonstandard', 'rating', 'shortDesc']; + const overrideItemKeys = ['desc', 'fling', 'isNonstandard', 'naturalGift', 'shortDesc']; // // Past gen table @@ -1130,13 +1131,16 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } } - const overrideItemDesc = {}; - BattleTeambuilderTable[gen].overrideItemDesc = overrideItemDesc; + const overrideItemData = {}; + BattleTeambuilderTable[gen].overrideItemData = overrideItemData; for (const id in genData.Items) { const curEntry = genDex.items.get(id); const nextEntry = nextGenDex.items.get(id); - if ((curEntry.shortDesc || curEntry.desc) !== (nextEntry.shortDesc || nextEntry.desc)) { - overrideItemDesc[id] = (curEntry.shortDesc || curEntry.desc); + for (const key of overrideItemKeys) { + if (JSON.stringify(curEntry[key]) !== JSON.stringify(nextEntry[key])) { + if (!overrideItemData[id]) overrideItemData[id] = {}; + overrideItemData[id][key] = curEntry[key]; + } } } @@ -1205,6 +1209,19 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); } } } + + const overrideItemData = {}; + BattleTeambuilderTable[mod].overrideItemData = overrideItemData; + for (const id in modData.Items) { + const modEntry = modDex.items.get(id); + const parentEntry = parentDex.items.get(id); + for (const key of overrideItemKeys) { + if (JSON.stringify(modEntry[key]) !== JSON.stringify(parentEntry[key])) { + if (!overrideItemData[id]) overrideItemData[id] = {}; + overrideItemData[id][key] = modEntry[key]; + } + } + } } buf += `exports.BattleTeambuilderTable = JSON.parse('${JSON.stringify(BattleTeambuilderTable).replace(/['\\]/g, "\\$&")}');\n\n`; diff --git a/play.pokemonshowdown.com/src/battle-dex.ts b/play.pokemonshowdown.com/src/battle-dex.ts index 72c8c45858..33065186f6 100644 --- a/play.pokemonshowdown.com/src/battle-dex.ts +++ b/play.pokemonshowdown.com/src/battle-dex.ts @@ -904,11 +904,16 @@ class ModdedDex { let data = {...Dex.items.get(name)}; - for (let i = this.gen; i < 9; i++) { - const table = window.BattleTeambuilderTable['gen' + i]; - if (id in table.overrideItemDesc) { - data.shortDesc = table.overrideItemDesc[id]; - break; + for (let i = Dex.gen - 1; i >= this.gen; i--) { + const table = window.BattleTeambuilderTable[`gen${i}`]; + if (id in table.overrideItemData) { + Object.assign(data, table.overrideItemData[id]); + } + } + if (this.modid !== `gen${this.gen}`) { + const table = window.BattleTeambuilderTable[this.modid]; + if (id in table.overrideItemData) { + Object.assign(data, table.overrideItemData[id]); } } From 7779bce67290e159df9631c2868e3ad74fd5b485 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Thu, 20 Jun 2024 21:34:32 -0400 Subject: [PATCH 675/770] Teambuilder: Update Smogdex links --- play.pokemonshowdown.com/js/client-teambuilder.js | 1 + 1 file changed, 1 insertion(+) diff --git a/play.pokemonshowdown.com/js/client-teambuilder.js b/play.pokemonshowdown.com/js/client-teambuilder.js index 33a6ef4eec..6aef15fe4f 100644 --- a/play.pokemonshowdown.com/js/client-teambuilder.js +++ b/play.pokemonshowdown.com/js/client-teambuilder.js @@ -2231,6 +2231,7 @@ case 'Sawsbuck': case 'Shellos': case 'Sinistea': + case 'Tatsugiri': case 'Vivillon': break; default: From dd253d209f3d2c9f9a5791c7acdff27893e2eef2 Mon Sep 17 00:00:00 2001 From: shrianshChari <30420527+shrianshChari@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:24:40 -0700 Subject: [PATCH 676/770] Add Psychic Noise animation (#2254) * Add Psychic Noise animation * Satisfy linter --- .../src/battle-animations-moves.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/play.pokemonshowdown.com/src/battle-animations-moves.ts b/play.pokemonshowdown.com/src/battle-animations-moves.ts index 4979d272ad..38c987d09f 100644 --- a/play.pokemonshowdown.com/src/battle-animations-moves.ts +++ b/play.pokemonshowdown.com/src/battle-animations-moves.ts @@ -35704,6 +35704,47 @@ export const BattleMoveAnims: AnimTable = { }, 'swing'); }, }, + psychicnoise: { + anim(scene, [attacker, defender]) { + scene.showEffect('mistball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0, + opacity: 0.8, + time: 0, + }, { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 5, + opacity: 0.1, + time: 750, + }, 'linear'); + scene.showEffect('poisonwisp', { + x: defender.x - 20, + y: defender.y + 20, + z: defender.z, + scale: 0, + opacity: 1, + time: 900, + }, { + scale: 2, + opacity: 0, + }, 'decel'); + scene.showEffect('poisonwisp', { + x: defender.x + 20, + y: defender.y + 20, + z: defender.z, + scale: 0, + opacity: 1, + time: 1050, + }, { + scale: 2, + opacity: 0, + }, 'decel'); + }, + }, }; // placeholder animations From 63d2a1f7f1ef82a5f5ef60a82f8dace1a75425ed Mon Sep 17 00:00:00 2001 From: Karthik <32044378+Karthik99999@users.noreply.github.com> Date: Wed, 26 Jun 2024 01:33:50 -0400 Subject: [PATCH 677/770] Replays: Fix More Replays button on mobile (#2255) --- replay.pokemonshowdown.com/src/replays-battle.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replay.pokemonshowdown.com/src/replays-battle.tsx b/replay.pokemonshowdown.com/src/replays-battle.tsx index 93fe2a45e4..fb96324f38 100644 --- a/replay.pokemonshowdown.com/src/replays-battle.tsx +++ b/replay.pokemonshowdown.com/src/replays-battle.tsx @@ -494,7 +494,7 @@ export class BattlePanel extends preact.Component<{id: string}> { {/* {} {this.keyCode} */}

      :

       

      } {!PSRouter.showingLeft() &&

      - More replays + More replays

      } ; } From 917298aa3f26fb9d919d035ae2e1309db945936f Mon Sep 17 00:00:00 2001 From: Distrib Date: Wed, 26 Jun 2024 09:33:53 +0200 Subject: [PATCH 678/770] Add Elo filter 1000 (#2249) PR for https://www.smogon.com/forums/threads/give-an-option-for-1000-minimum-elo-in-the-battles-tab-to-filter-out-challenge-battles.3743305/ --- play.pokemonshowdown.com/js/client-rooms.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/js/client-rooms.js b/play.pokemonshowdown.com/js/client-rooms.js index a6f48fb191..a25f860281 100644 --- a/play.pokemonshowdown.com/js/client-rooms.js +++ b/play.pokemonshowdown.com/js/client-rooms.js @@ -224,7 +224,7 @@ var buf = '

      '; buf += '

      '; - buf += ''; + buf += ''; buf += '

      '; buf += '

      Loading...

      '; buf += '
      '; From baf31cfe063d68a31004e22a31207c8ecea7bdd7 Mon Sep 17 00:00:00 2001 From: dot-Comfey <84290266+dot-Comfey@users.noreply.github.com> Date: Thu, 4 Jul 2024 13:04:02 -0700 Subject: [PATCH 679/770] Properly display legal egg moves in teambuilder (#2256) --- build-tools/build-indexes | 1 + .../src/battle-dex-search.ts | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index cbec9f3f61..68e5b01757 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -898,6 +898,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (gens.indexOf(9) >= 0 && learnset[moveid].some(x => x[0] === '9' && x !== '9V')) { learnsets[id][moveid] += 'a'; } + if (gens.indexOf(9) >= 0 && learnset[moveid].some(x => x === '9E')) learnsets[id][moveid] += 'e'; } } const G2Learnsets = Dex.mod('gen2').data.Learnsets; diff --git a/play.pokemonshowdown.com/src/battle-dex-search.ts b/play.pokemonshowdown.com/src/battle-dex-search.ts index c30a12f6c1..a77879b845 100644 --- a/play.pokemonshowdown.com/src/battle-dex-search.ts +++ b/play.pokemonshowdown.com/src/battle-dex-search.ts @@ -773,6 +773,14 @@ abstract class BattleTypedSearch { const next = lsetSpecies.battleOnly || lsetSpecies.changesFrom || lsetSpecies.prevo; if (next) return toID(next); + if (!lsetSpecies.prevo && lsetSpecies.baseSpecies && this.dex.species.get(lsetSpecies.baseSpecies).prevo) { + let baseEvo = this.dex.species.get(lsetSpecies.baseSpecies); + while (baseEvo.prevo) { + baseEvo = this.dex.species.get(baseEvo.prevo); + } + return toID(baseEvo); + } + return '' as ID; } protected canLearn(speciesid: ID, moveid: ID) { @@ -1579,6 +1587,14 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { if (regionBornLegality && !learnsetEntry.includes(minGenCode[dex.gen])) { continue; } + const currentSpecies = dex.species.get(learnsetid); + const originalSpecies = dex.species.get(species.id); + if ( + currentSpecies.baseSpecies !== originalSpecies.baseSpecies && !originalSpecies.prevo && + !originalSpecies.changesFrom && (!learnsetEntry.includes('e') || dex.gen !== 9) + ) { + continue; + } if ( !learnsetEntry.includes(gen) && (!isTradebacks ? true : !(move.gen <= dex.gen && learnsetEntry.includes('' + (dex.gen + 1)))) From 2717e96fabe342790d30f1b5cf8053f9b4be6fad Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sat, 6 Jul 2024 15:07:51 +0000 Subject: [PATCH 680/770] Include smogtours in "server down" message --- play.pokemonshowdown.com/js/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/js/client.js b/play.pokemonshowdown.com/js/client.js index 9f2c953bdb..75611b0390 100644 --- a/play.pokemonshowdown.com/js/client.js +++ b/play.pokemonshowdown.com/js/client.js @@ -405,7 +405,7 @@ function toId() { this.supports = {}; // down - // if (document.location.hostname === 'play.pokemonshowdown.com') this.down = true; + // if (document.location.hostname === 'play.pokemonshowdown.com' || document.location.hostname === 'smogtours.psim.us') this.down = true; // this.down = true; this.addRoom(''); From a0bab922fe2eaab7f945f99abb1b62806bb3b08f Mon Sep 17 00:00:00 2001 From: shrianshChari <30420527+shrianshChari@users.noreply.github.com> Date: Sat, 6 Jul 2024 20:22:31 -0700 Subject: [PATCH 681/770] Add teambuilder support for BW 1 (#2257) --- build-tools/build-indexes | 24 +++++++++++++++++-- .../src/battle-dex-search.ts | 14 ++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index 68e5b01757..73e0403036 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -322,7 +322,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const LC = GENS.map(num => num + 0.7); const STADIUM = [2.04, 1.04]; const NATDEX = [9.1, 8.1]; - const OTHER = [9.9, 9.6, 9.411, 9.41, 9.401, 9.4, 9.2, -9.4, -9.401, 8.6, 8.4, 8.2, 8.1, -8.4, -8.6, 7.1]; + const OTHER = [9.9, 9.6, 9.411, 9.41, 9.401, 9.4, 9.2, -9.4, -9.401, 8.6, 8.4, 8.2, 8.1, -8.4, -8.6, 7.1, 5.1]; // process.stdout.write("\n "); for (const genIdent of [...GENS, ...DOUBLES, ...VGC, ...NFE, ...STADIUM, ...OTHER, ...NATDEX, ...LC]) { @@ -341,6 +341,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const isGen9BH = genIdent === 9.9; const isSSB = genIdent === 9.6; const genNum = Math.floor(isDoubles ? -genIdent : genIdent); + const isBW1 = genIdent === 5.1; const gen = (() => { let genStr = 'gen' + genNum; if (isSSDLC1) genStr += 'dlc1'; @@ -350,6 +351,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (isSVDLC1) genStr += 'dlc1'; if (isStadium) genStr += 'stadium' + (genNum > 1 ? genNum : ''); if (isSSB) genStr += 'ssb'; + if (isBW1) genStr += 'bw1'; return genStr; })(); // process.stdout.write("" + gen + (isDoubles ? " doubles" : "") + "... "); @@ -557,6 +559,14 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable.ubersUUBans = ubersUUBans; BattleTeambuilderTable.monotypeBans = monotypeBans; BattleTeambuilderTable.formatSlices = formatSlices; + } else if (isBW1) { + BattleTeambuilderTable[gen] = {}; + BattleTeambuilderTable[gen].overrideTier = overrideTier; + BattleTeambuilderTable[gen].tiers = tiers; + BattleTeambuilderTable[gen].items = items; + BattleTeambuilderTable[gen].formatSlices = formatSlices; + BattleTeambuilderTable[gen].nonstandardMoves = nonstandardMoves; + BattleTeambuilderTable[gen].learnsets = {}; } else { BattleTeambuilderTable[gen] = {}; BattleTeambuilderTable[gen].overrideTier = overrideTier; @@ -915,6 +925,16 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (minGen === 1) learnsets[id][moveid] = '12' + learnsets[id][moveid]; } } + const G5BW1Learnsets = Dex.mod('gen5bw1').data.Learnsets; + for (const id in G5BW1Learnsets) { + const species = Dex.mod('gen5bw1').species.get(id); + if (species.isNonstandard && !['Unobtainable', 'CAP'].includes(species.isNonstandard)) continue; + const learnset = G5BW1Learnsets[id].learnset; + BattleTeambuilderTable['gen5bw1'].learnsets[id] = {}; + for (const moveid in learnset) { + BattleTeambuilderTable['gen5bw1'].learnsets[id][moveid] = '5'; + } + } const LGLearnsets = Dex.mod('gen7letsgo').data.Learnsets; for (const id in LGLearnsets) { const species = Dex.mod('gen7letsgo').species.get(id); @@ -1166,7 +1186,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); // Mods // - for (const mod of ['gen7letsgo', 'gen8bdsp', 'gen9ssb']) { + for (const mod of ['gen5bw1', 'gen7letsgo', 'gen8bdsp', 'gen9ssb']) { const modDex = Dex.mod(mod); const modData = modDex.data; const parentDex = Dex.forGen(modDex.gen); diff --git a/play.pokemonshowdown.com/src/battle-dex-search.ts b/play.pokemonshowdown.com/src/battle-dex-search.ts index a77879b845..e2a1977572 100644 --- a/play.pokemonshowdown.com/src/battle-dex-search.ts +++ b/play.pokemonshowdown.com/src/battle-dex-search.ts @@ -549,7 +549,7 @@ abstract class BattleTypedSearch { */ set: PokemonSet | null = null; - protected formatType: 'doubles' | 'bdsp' | 'bdspdoubles' | 'letsgo' | 'metronome' | 'natdex' | 'nfe' | + protected formatType: 'doubles' | 'bdsp' | 'bdspdoubles' | 'bw1' | 'letsgo' | 'metronome' | 'natdex' | 'nfe' | 'ssdlc1' | 'ssdlc1doubles' | 'predlc' | 'predlcdoubles' | 'predlcnatdex' | 'svdlc1' | 'svdlc1doubles' | 'svdlc1natdex' | 'stadium' | 'lc' | null = null; @@ -628,6 +628,10 @@ abstract class BattleTypedSearch { format = format.slice(4) as ID; this.dex = Dex.mod('gen8bdsp' as ID); } + if (format.includes('bw1')) { + this.formatType = 'bw1'; + this.dex = Dex.mod('gen5bw1' as ID); + } if (format === 'partnersincrime') this.formatType = 'doubles'; if (format.startsWith('ffa') || format === 'freeforall') this.formatType = 'doubles'; if (format.includes('letsgo')) { @@ -747,6 +751,7 @@ abstract class BattleTypedSearch { let table = BattleTeambuilderTable; if (this.formatType?.startsWith('bdsp')) table = table['gen8bdsp']; if (this.formatType === 'letsgo') table = table['gen7letsgo']; + if (this.formatType === 'bw1') table = table['gen5bw1']; if (speciesid in table.learnsets) return speciesid; const species = this.dex.species.get(speciesid); if (!species.exists) return '' as ID; @@ -813,6 +818,7 @@ abstract class BattleTypedSearch { let table = BattleTeambuilderTable; if (this.formatType?.startsWith('bdsp')) table = table['gen8bdsp']; if (this.formatType === 'letsgo') table = table['gen7letsgo']; + if (this.formatType === 'bw1') table = table['gen5bw1']; let learnset = table.learnsets[learnsetid]; if (learnset && (moveid in learnset) && (!this.format.startsWith('tradebacks') ? learnset[moveid].includes(genChar) : learnset[moveid].includes(genChar) || @@ -833,6 +839,7 @@ abstract class BattleTypedSearch { this.formatType === 'letsgo' ? 'gen7letsgo' : this.formatType === 'bdsp' ? 'gen8bdsp' : this.formatType === 'bdspdoubles' ? 'gen8bdspdoubles' : + this.formatType === 'bw1' ? 'gen5bw1' : this.formatType === 'nfe' ? `gen${gen}nfe` : this.formatType === 'lc' ? `gen${gen}lc` : this.formatType === 'ssdlc1' ? 'gen8dlc1' : @@ -956,6 +963,8 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { table = table['gen8' + this.formatType]; } else if (this.formatType === 'letsgo') { table = table['gen7letsgo']; + } else if (this.formatType === 'bw1') { + table = table['gen5bw1']; } else if (this.formatType === 'natdex') { table = table['gen' + dex.gen + 'natdex']; } else if (this.formatType === 'metronome') { @@ -1231,6 +1240,8 @@ class BattleItemSearch extends BattleTypedSearch<'item'> { let table = BattleTeambuilderTable; if (this.formatType?.startsWith('bdsp')) { table = table['gen8bdsp']; + } else if (this.formatType === 'bw1') { + table = table['gen5bw1']; } else if (this.formatType === 'natdex') { table = table['gen' + this.dex.gen + 'natdex']; } else if (this.formatType === 'metronome') { @@ -1574,6 +1585,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { let lsetTable = BattleTeambuilderTable; if (this.formatType?.startsWith('bdsp')) lsetTable = lsetTable['gen8bdsp']; if (this.formatType === 'letsgo') lsetTable = lsetTable['gen7letsgo']; + if (this.formatType === 'bw1') lsetTable = lsetTable['gen5bw1']; if (this.formatType?.startsWith('ssdlc1')) lsetTable = lsetTable['gen8dlc1']; if (this.formatType?.startsWith('predlc')) lsetTable = lsetTable['gen9predlc']; if (this.formatType?.startsWith('svdlc1')) lsetTable = lsetTable['gen9dlc1']; From 0774605f3a21bd85566531f95b1b2d26e15165be Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sun, 7 Jul 2024 09:08:04 +0000 Subject: [PATCH 682/770] Fix crash in Replays --- replay.pokemonshowdown.com/index.template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replay.pokemonshowdown.com/index.template.php b/replay.pokemonshowdown.com/index.template.php index ab8be04677..5e5fffb54b 100644 --- a/replay.pokemonshowdown.com/index.template.php +++ b/replay.pokemonshowdown.com/index.template.php @@ -273,7 +273,7 @@ function gtag(){dataLayer.push(arguments);} echo ''."\n"; - if ($replay['safe_inputlog'] || $manage) { + if (@$replay['safe_inputlog'] || $manage) { if (!$replay['safe_inputlog']) echo ''."\n"; echo ' + From 04ed96ba170f18a1f008fd53c937d67fc449f4aa Mon Sep 17 00:00:00 2001 From: dot-Comfey <84290266+dot-Comfey@users.noreply.github.com> Date: Mon, 2 Sep 2024 21:50:22 -0700 Subject: [PATCH 726/770] Use only current line in tab-completing commands (#2279) * Use only current line in tab-completing commands https://www.smogon.com/forums/threads/bug-report.3749269/ At this point, it's a bit more than a bug fix. * Update client-chat.js Changed stuff that npm run test did not like. * Restore subcommand behavior --- play.pokemonshowdown.com/js/client-chat.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/play.pokemonshowdown.com/js/client-chat.js b/play.pokemonshowdown.com/js/client-chat.js index c64cc78bc4..62c683e07a 100644 --- a/play.pokemonshowdown.com/js/client-chat.js +++ b/play.pokemonshowdown.com/js/client-chat.js @@ -359,10 +359,11 @@ var m2 = /^([\s\S!/]*?)([A-Za-z0-9][^, \n]* [^, ]*)$/.exec(prefix); if (!m1 && !m2) return true; var cmds = this.tabComplete.commands; + var currentLine = prefix.substr(prefix.lastIndexOf('\n') + 1); var shouldSearchCommands = !cmds || (cmds.length ? !!cmds.length && !cmds.filter(function (x) { - return x.startsWith(prefix); + return x.startsWith(currentLine); }).length : prefix != this.tabComplete.prefix); - var isCommandSearch = (text.startsWith('/') && !text.startsWith('//')) || text.startsWith('!'); + var isCommandSearch = (currentLine.startsWith('/') && !currentLine.startsWith('//')) || currentLine.startsWith('!'); var resultsExist = this.tabComplete.lastSearch === text && this.tabComplete.commands; if (isCommandSearch && shouldSearchCommands && !resultsExist) { if (this.tabComplete.searchPending) return true; // wait @@ -378,7 +379,7 @@ self.handleTabComplete($textbox, reverse); } }); - this.send('/crq cmdsearch ' + text); + this.send('/crq cmdsearch ' + currentLine); return true; } else if (!isCommandSearch) { delete this.tabComplete.isCommand; @@ -447,7 +448,8 @@ if (!substituteUser) return true; var name = typeof substituteUser === 'object' ? substituteUser.name : substituteUser; name = Dex.getShortName(name); - var fullPrefix = this.tabComplete.prefix.substr(0, candidate[1]) + name; + var prefixIndex = candidate[1].toString().charAt(0) === '/' ? prefix.lastIndexOf('\n') + 1 : candidate[1]; + var fullPrefix = this.tabComplete.prefix.substr(0, prefixIndex) + name; $textbox.val(fullPrefix + text.substr(idx)); var pos = fullPrefix.length; $textbox[0].setSelectionRange(pos, pos); From 2b095bd32a5afbe61d3ee4c63e44f29f686aeffc Mon Sep 17 00:00:00 2001 From: PartMan <47669599+PartMan7@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:32:37 +0530 Subject: [PATCH 727/770] fix: Pass this context correctly to updateTeamList (#2277) --- play.pokemonshowdown.com/js/client-teambuilder.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/play.pokemonshowdown.com/js/client-teambuilder.js b/play.pokemonshowdown.com/js/client-teambuilder.js index be22d105f3..658eafd74d 100644 --- a/play.pokemonshowdown.com/js/client-teambuilder.js +++ b/play.pokemonshowdown.com/js/client-teambuilder.js @@ -3246,21 +3246,21 @@ }, searchChange: function (e) { var DEBOUNCE_THRESHOLD_TEAMS = 500; + var searchVal = e.currentTarget.value; + var self = this; function updateTeamList() { // 91 for right CMD / 93 for left CMD / 17 for CTL if (e.keyCode !== 91 && e.keyCode !== 93 && e.keyCode !== 17) { - this.curSearchVal = searchVal; + self.curSearchVal = searchVal; } - this.updateTeamList(); + self.updateTeamList(); } // If the user has a lot of teams, search is debounced to // ensure this isn't called too frequently while typing if (Storage.teams.length > DEBOUNCE_THRESHOLD_TEAMS) { if (this.searchTimeout) clearTimeout(this.searchTimeout); - - var searchVal = e.currentTarget.value; - this.searchTimeout = setTimeout(updateTeamList.bind(this), 400); + this.searchTimeout = setTimeout(updateTeamList, 400); } else updateTeamList(); }, From d70643646af1d1fc667385b3c2380647c33188b7 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Tue, 3 Sep 2024 18:22:48 -0700 Subject: [PATCH 728/770] Fix Transform Palafin-Hero interaction --- .../src/battle-animations.ts | 19 ++++++++++++++----- .../src/battle-scene-stub.ts | 2 +- play.pokemonshowdown.com/src/battle.ts | 6 ++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index 289a50c254..4d570d3edc 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -1516,8 +1516,8 @@ export class BattleScene implements BattleSceneStub { updateStatbarIfExists(pokemon: Pokemon, updatePrevhp?: boolean, updateHp?: boolean) { return pokemon.sprite.updateStatbarIfExists(pokemon, updatePrevhp, updateHp); } - animTransform(pokemon: Pokemon, isCustomAnim?: boolean, isPermanent?: boolean) { - return pokemon.sprite.animTransform(pokemon, isCustomAnim, isPermanent); + animTransform(pokemon: Pokemon, useSpeciesAnim?: boolean, isPermanent?: boolean) { + return pokemon.sprite.animTransform(pokemon, useSpeciesAnim, isPermanent); } clearEffects(pokemon: Pokemon) { return pokemon.sprite.clearEffects(); @@ -2500,7 +2500,12 @@ export class PokemonSprite extends Sprite { }); } } - animTransform(pokemon: Pokemon, isCustomAnim?: boolean, isPermanent?: boolean) { + /** + * @param pokemon + * @param useSpeciesAnim false = Transform the move or Imposter the ability + * @param isPermanent false = reverts on switch-out + */ + animTransform(pokemon: Pokemon, useSpeciesAnim?: boolean, isPermanent?: boolean) { if (!this.scene.animating && !isPermanent) return; let sp = Dex.getSpriteData(pokemon, this.isFrontSprite, { gen: this.scene.gen, @@ -2527,8 +2532,9 @@ export class PokemonSprite extends Sprite { if (!this.scene.animating) return; let speciesid = toID(pokemon.getSpeciesForme()); let doCry = false; + let skipAnim = false; const scene = this.scene; - if (isCustomAnim) { + if (useSpeciesAnim) { if (speciesid === 'kyogreprimal') { BattleOtherAnims.primalalpha.anim(scene, [this]); doCry = true; @@ -2546,6 +2552,8 @@ export class PokemonSprite extends Sprite { BattleOtherAnims.schoolingout.anim(scene, [this]); } else if (speciesid === 'mimikyubusted' || speciesid === 'mimikyubustedtotem') { // standard animation + } else if (speciesid === 'palafinhero') { + skipAnim = true; } else { BattleOtherAnims.megaevo.anim(scene, [this]); doCry = true; @@ -2561,9 +2569,10 @@ export class PokemonSprite extends Sprite { xscale: 0, opacity: 0, }, sp)); - if (speciesid === 'palafinhero') { + if (skipAnim) { this.$el.replaceWith($newEl); this.$el = $newEl; + this.animReset(); } else { this.$el.animate(this.scene.pos({ x: this.x, diff --git a/play.pokemonshowdown.com/src/battle-scene-stub.ts b/play.pokemonshowdown.com/src/battle-scene-stub.ts index 44b2ab4189..7fc99892f5 100644 --- a/play.pokemonshowdown.com/src/battle-scene-stub.ts +++ b/play.pokemonshowdown.com/src/battle-scene-stub.ts @@ -67,7 +67,7 @@ export class BattleSceneStub { resetStatbar(pokemon: Pokemon, startHidden?: boolean) { } updateStatbar(pokemon: Pokemon, updatePrevhp?: boolean, updateHp?: boolean) { } updateStatbarIfExists(pokemon: Pokemon, updatePrevhp?: boolean, updateHp?: boolean) { } - animTransform(pokemon: Pokemon, isCustomAnim?: boolean, isPermanent?: boolean) { } + animTransform(pokemon: Pokemon, useSpeciesAnim?: boolean, isPermanent?: boolean) { } clearEffects(pokemon: Pokemon) { } removeTransform(pokemon: Pokemon) { } animFaint(pokemon: Pokemon) { } diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index a5595832f1..60b955ae6d 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -2450,8 +2450,7 @@ export class Battle { poke.details = args[2]; poke.searchid = args[1].substr(0, 2) + args[1].substr(3) + '|' + args[2]; - let isCustomAnim = species.id !== 'palafinhero'; - this.scene.animTransform(poke, isCustomAnim, true); + this.scene.animTransform(poke, true, true); this.log(args, kwArgs); break; } @@ -2489,7 +2488,6 @@ export class Battle { let poke = this.getPokemon(args[1])!; let species = Dex.species.get(args[2]); let fromeffect = Dex.getEffect(kwArgs.from); - let isCustomAnim = species.name.startsWith('Wishiwashi'); if (!poke.getSpeciesForme().endsWith('-Gmax') && !species.name.endsWith('-Gmax')) { poke.removeVolatile('typeadd' as ID); poke.removeVolatile('typechange' as ID); @@ -2500,7 +2498,7 @@ export class Battle { this.activateAbility(poke, fromeffect); } poke.addVolatile('formechange' as ID, species.name); // the formechange volatile reminds us to revert the sprite change on switch-out - this.scene.animTransform(poke, isCustomAnim); + this.scene.animTransform(poke, true); this.log(args, kwArgs); break; } From 5512e76866463722c60ec09f1ab6f5c1e31db67c Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Thu, 5 Sep 2024 15:51:06 -0500 Subject: [PATCH 729/770] Ladder: Add GXE filtering for ladders with a max elo above 1500 --- lib/ntbb-ladder.lib.php | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/ntbb-ladder.lib.php b/lib/ntbb-ladder.lib.php index 7e4988b373..aeaf04f64f 100644 --- a/lib/ntbb-ladder.lib.php +++ b/lib/ntbb-ladder.lib.php @@ -233,10 +233,32 @@ function getTop($prefix = null) { "SELECT * FROM (SELECT * FROM `{$ladderdb->prefix}ladder` WHERE `formatid` = ? ORDER BY `elo` DESC LIMIT $overfetch) AS `unusedalias` WHERE `userid` LIKE ? LIMIT $limit", [$this->formatid, "$prefix%"] ); + $res = $ladderdb->query( + "WITH `max_elo` AS ( + SELECT MAX(elo) AS `max_elo` FROM `{$ladderdb->prefix}ladder` WHERE `formatid` = ? + ), + `rpr_filtered` AS ( + SELECT * FROM `{$ladderdb->prefix}ladder` WHERE + ((SELECT `max_elo` FROM `max_elo`) <= 1500 OR `rprd` <= 100) + AND `formatid` = ? + ) + SELECT * FROM + (SELECT * FROM `rpr_filtered` WHERE `formatid` = ? ORDER BY `elo` DESC LIMIT {$overfetch}) + AS `unusedalias` WHERE `userid` LIKE ? LIMIT $limit", + [$this->formatid, $this->formatid, $this->formatid, "$prefix%"] + ); } else { $res = $ladderdb->query( - "SELECT * FROM `{$ladderdb->prefix}ladder` WHERE `formatid` = ? ORDER BY `elo` DESC LIMIT $limit", - [$this->formatid] + "WITH max_elo AS ( + SELECT MAX(elo) AS max_elo FROM `{$ladderdb->prefix}ladder` WHERE `formatid` = ? + ), + rpr_filtered AS ( + SELECT * FROM `{$ladderdb->prefix}ladder` WHERE + ((SELECT `max_elo` FROM `max_elo`) <= 1500 OR `rprd` <= 100) + AND `formatid` = ? + ) + SELECT * FROM `rpr_filtered` ORDER BY `elo` DESC LIMIT $limit", + [$this->formatid, $this->formatid] ); } From b625bf7ca04bb1a92411ed69ef870eb016b9e780 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Thu, 26 Sep 2024 18:25:22 -0500 Subject: [PATCH 730/770] Add a protocol message for opening external sites Limited to use by the main server for obvious reasons. Intended to use for linking PS-Smogon accounts. No one should be using this otherwise, but just in case I've put an interstice guard on any non-whitelisted links. --- play.pokemonshowdown.com/js/client.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/play.pokemonshowdown.com/js/client.js b/play.pokemonshowdown.com/js/client.js index abd53ebf71..e4fff3c707 100644 --- a/play.pokemonshowdown.com/js/client.js +++ b/play.pokemonshowdown.com/js/client.js @@ -1245,6 +1245,15 @@ function toId() { document.location.reload(true); break; + case 'openpage': + // main server only, side servers don't get this + if (Config.server.id !== 'showdown') break; + var uri = parts[1]; + if (!BattleLog.interstice.isWhitelisted(uri)) { + uri = BattleLog.interstice.getURI(uri); + } + this.openInNewWindow(uri); + break; case 'c': case 'chat': if (parts[1] === '~') { From 9a838386222961cbc0887e34a1e42579098dc716 Mon Sep 17 00:00:00 2001 From: demir <46607042+swordfishtr@users.noreply.github.com> Date: Mon, 30 Sep 2024 13:44:54 +0300 Subject: [PATCH 731/770] Fixed missing HTML sanitization (again) (#2284) --- play.pokemonshowdown.com/js/client-teambuilder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/js/client-teambuilder.js b/play.pokemonshowdown.com/js/client-teambuilder.js index 658eafd74d..fd2593e4fd 100644 --- a/play.pokemonshowdown.com/js/client-teambuilder.js +++ b/play.pokemonshowdown.com/js/client-teambuilder.js @@ -494,7 +494,7 @@ // support dragging and dropping buttons. buf += '
    • ' + formatText + '' + BattleLog.escapeHTML(team.name) + '
      '; + buf += '" draggable="true">' + BattleLog.escapeHTML(formatText) + '' + BattleLog.escapeHTML(team.name) + '
      '; buf += Storage.getTeamIcons(team); buf += '
    • '; From aed9c265aa205997774d13988392c77cb6f034d1 Mon Sep 17 00:00:00 2001 From: dot-Comfey <84290266+dot-Comfey@users.noreply.github.com> Date: Mon, 30 Sep 2024 07:27:18 -0700 Subject: [PATCH 732/770] Fix searching for Ursaluna-Bloodmoon by moves (#2286) https://www.smogon.com/forums/threads/bug-report-unsure.3752081/ See also https://github.com/smogon/pokemon-showdown/pull/10584 --- .../src/battle-dex-search.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-dex-search.ts b/play.pokemonshowdown.com/src/battle-dex-search.ts index 6fd8588574..e226ed00f1 100644 --- a/play.pokemonshowdown.com/src/battle-dex-search.ts +++ b/play.pokemonshowdown.com/src/battle-dex-search.ts @@ -821,9 +821,11 @@ abstract class BattleTypedSearch { if (this.formatType === 'letsgo') table = table['gen7letsgo']; if (this.formatType === 'bw1') table = table['gen5bw1']; let learnset = table.learnsets[learnsetid]; + const eggMovesOnly = this.eggMovesOnly(learnsetid, speciesid); if (learnset && (moveid in learnset) && (!this.format.startsWith('tradebacks') ? learnset[moveid].includes(genChar) : - learnset[moveid].includes(genChar) || - (learnset[moveid].includes(`${gen + 1}`) && move.gen === gen))) { + learnset[moveid].includes(genChar) || (learnset[moveid].includes(`${gen + 1}`) && move.gen === gen)) && + (!eggMovesOnly || (learnset[moveid].includes('e') && this.dex.gen === 9)) + ) { return true; } learnsetid = this.nextLearnsetid(learnsetid, speciesid, true); @@ -873,6 +875,15 @@ abstract class BattleTypedSearch { return pokemon.tier; } + eggMovesOnly(child: ID, father: ID) { + if (this.dex.species.get(child).baseSpecies === this.dex.species.get(father).baseSpecies) return false; + const baseSpecies = father; + while (father) { + if (child === father) return false; + father = this.nextLearnsetid(father, baseSpecies); + } + return true; + } abstract getTable(): {[id: string]: any}; abstract getDefaultResults(): SearchRow[]; abstract getBaseResults(): SearchRow[]; @@ -1615,15 +1626,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { if (regionBornLegality && !learnsetEntry.includes(minGenCode[dex.gen])) { continue; } - const currentSpecies = dex.species.get(learnsetid); - const originalSpecies = dex.species.get(species.id); - let nextSpecies = this.nextLearnsetid(species.id, species.id); - while (nextSpecies) { - if (nextSpecies === learnsetid) break; - nextSpecies = this.nextLearnsetid(nextSpecies, species.id); - } if ( - currentSpecies.baseSpecies !== originalSpecies.baseSpecies && !nextSpecies && + this.eggMovesOnly(learnsetid, species.id) && (!learnsetEntry.includes('e') || dex.gen !== 9) ) { continue; From 0555fa2975d670aaab2223dd2b9779850aa97a23 Mon Sep 17 00:00:00 2001 From: demir <46607042+swordfishtr@users.noreply.github.com> Date: Mon, 30 Sep 2024 17:28:50 +0300 Subject: [PATCH 733/770] Teambuilder: Fix endless loop when packing teams (#2285) --- play.pokemonshowdown.com/js/storage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/js/storage.js b/play.pokemonshowdown.com/js/storage.js index 3eeaa4e332..8ca36a79bf 100644 --- a/play.pokemonshowdown.com/js/storage.js +++ b/play.pokemonshowdown.com/js/storage.js @@ -1107,7 +1107,7 @@ Storage.unpackTeam = function (buf) { set.dynamaxLevel = (misc[4] ? Number(misc[4]) : 10); set.teraType = misc[5]; } - if (j < 0) break; + if (j < 0 || buf.indexOf('|', j) < 0) break; i = j + 1; } From 9825f5e88698eb8aedd88e632bd406f5b0c32638 Mon Sep 17 00:00:00 2001 From: HiZo <96159984+HisuianZoroark@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:29:10 -0400 Subject: [PATCH 734/770] Fix Quark Drive/Protosynthesis visual bug when losing ability (#2253) --- play.pokemonshowdown.com/src/battle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index 60b955ae6d..4a9b73e9af 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -2700,7 +2700,7 @@ export class Battle { let fromeffect = Dex.getEffect(kwArgs.from); poke.removeVolatile(effect.id); - if (kwArgs.silent) { + if (kwArgs.silent && !(effect.id === 'protosynthesis' || effect.id === 'quarkdrive')) { // do nothing } else { switch (effect.id) { From 2cc05690511ea8d5c89cb19d87c8d0f529bf95dd Mon Sep 17 00:00:00 2001 From: Glaze <35176230+Glazelf@users.noreply.github.com> Date: Tue, 1 Oct 2024 01:33:57 +0200 Subject: [PATCH 735/770] Update ladder names (#2282) * Update VGC names * Remove deprecated metagames * Update ladder.php * Update users.php * Update pokemonshowdown.com/users.php --------- Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com> --- pokemonshowdown.com/ladder.php | 49 +++++++++++++++++++++++----------- pokemonshowdown.com/users.php | 17 ++++++++---- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/pokemonshowdown.com/ladder.php b/pokemonshowdown.com/ladder.php index cde86b2fe7..719ba441bf 100644 --- a/pokemonshowdown.com/ladder.php +++ b/pokemonshowdown.com/ladder.php @@ -28,20 +28,27 @@ 'gen9pu' => 'PU', 'gen9lc' => 'Little Cup', 'gen9monotype' => 'Monotype', + 'gen9bssregh' => 'Battle Stadium Singles Regulation H', 'gen9anythinggoes' => 'Anything Goes', - 'gen9zu' => 'ZU', + 'gen9zu' => 'ZeroUsed', 'gen91v1' => '1v1', - 'gen9battlestadiumsingles' => 'Battle Stadium Singles', + 'gen9cap' => 'CAP', 'gen9randomdoublesbattle' => 'Random Doubles Battle', 'gen9doublesou' => 'Doubles OU', - 'gen9vgc2023regulationc' => 'VGC 2023 Regulation C', + 'gen9vgc2024regh' => 'VGC 2024 Regulation H', + 'gen9almostanyability' => 'Almost Any Ability', 'gen9balancedhackmons' => 'Balanced Hackmons', + 'gen9godlygift' => 'Godly Gift', + 'gen9inheritance' => 'Inheritance', 'gen9mixandmega' => 'Mix and Mega', - 'gen9almostanyability' => 'Almost Any Ability', + 'gen9partnersincrime' => 'Partners in Crime', + 'gen9sharedpower' => 'Shared Power', 'gen9stabmons' => 'STABmons', - 'gen9nfe' => 'NFE', - 'gen9godlygift' => 'Godly Gift', - 'gen8cap' => 'CAP', + 'gen9nationaldex' => 'National Dex OU', + 'gen9nationaldexubers' => 'National Dex Ubers', + 'gen9nationaldexuu' => 'National Dex UU', + 'gen9nationaldexmonotype' => 'National Dex Monotype', + 'gen9nationaldexdoubles' => 'National Dex Doubles', ); $format = $formatid; @@ -114,23 +121,33 @@
    +

    Find user diff --git a/pokemonshowdown.com/users.php b/pokemonshowdown.com/users.php index fa0c21fd79..71effe5ac3 100644 --- a/pokemonshowdown.com/users.php +++ b/pokemonshowdown.com/users.php @@ -63,17 +63,24 @@ 'gen9pu' => 'PU', 'gen9lc' => 'Little Cup', 'gen9monotype' => 'Monotype', - 'gen9battlestadiumsingles' => 'Battle Stadium Singles', + 'gen9bssregh' => 'Battle Stadium Singles Regulation H', 'gen9cap' => 'CAP', 'gen9randomdoublesbattle' => 'Random Doubles Battle', 'gen9doublesou' => 'Doubles OU', - 'gen9vgc2023' => 'VGC 2023', + 'gen9vgc2024regh' => 'VGC 2024 Regulation H', + 'gen9almostanyability' => 'Almost Any Ability', 'gen9balancedhackmons' => 'Balanced Hackmons', + 'gen9godlygift' => 'Godly Gift', + 'gen9inheritance' => 'Inheritance', 'gen9mixandmega' => 'Mix and Mega', - 'gen9almostanyability' => 'Almost Any Ability', + 'gen9partnersincrime' => 'Partners in Crime', + 'gen9sharedpower' => 'Shared Power', 'gen9stabmons' => 'STABmons', - 'gen9nfe' => 'NFE', - 'gen9godlygift' => 'Godly Gift', + 'gen9nationaldex' => 'National Dex OU', + 'gen9nationaldexubers' => 'National Dex Ubers', + 'gen9nationaldexuu' => 'National Dex UU', + 'gen9nationaldexmonotype' => 'National Dex Monotype', + 'gen9nationaldexdoubles' => 'National Dex Doubles', 'gen8randombattle' => '[Gen 8] Random Battle', 'gen8ou' => '[Gen 8] OU', 'gen7randombattle' => '[Gen 7] Random Battle', From 95bd7974b3085bedc1106de1d1c267d5bf3c2cf3 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:44:06 -0600 Subject: [PATCH 736/770] Add teambuilder support for 35 Pokes --- build-tools/build-indexes | 8 ++++++++ play.pokemonshowdown.com/src/battle-dex-search.ts | 14 +++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/build-tools/build-indexes b/build-tools/build-indexes index d0b1b58f3a..aa13c390fd 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -361,6 +361,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); const overrideTier = {}; const ubersUUBans = {}; const ndDoublesBans = {}; + const thirtyfivePokes = {}; const monotypeBans = {}; const nonstandardMoves = []; const gen5zuBans = {}; @@ -478,6 +479,10 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); if (ndDoubles.exists && Dex.formats.getRuleTable(ndDoubles).isBannedSpecies(species)) { ndDoublesBans[species.id] = 1; } + const nd35Pokes = Dex.formats.get(gen + 'nationaldex35pokes'); + if (nd35Pokes.exists && !Dex.formats.getRuleTable(nd35Pokes).isBannedSpecies(species)) { + thirtyfivePokes[species.id] = 1; + } } if (genNum >= 5) { if (genNum === 5) { @@ -511,6 +516,9 @@ process.stdout.write("Building `data/teambuilder-tables.js`... "); BattleTeambuilderTable['gen' + genNum + 'natdex'].ndDoublesBans = ndDoublesBans; BattleTeambuilderTable['gen' + genNum + 'natdex'].monotypeBans = monotypeBans; BattleTeambuilderTable['gen' + genNum + 'natdex'].formatSlices = formatSlices; + if (isNatDex && genNum === 9) { + BattleTeambuilderTable['gen' + genNum + 'natdex'].thirtyfivePokes = thirtyfivePokes; + } } else if (isMetBattle) { BattleTeambuilderTable[gen + 'metronome'] = {}; BattleTeambuilderTable[gen + 'metronome'].tiers = tiers; diff --git a/play.pokemonshowdown.com/src/battle-dex-search.ts b/play.pokemonshowdown.com/src/battle-dex-search.ts index e226ed00f1..a9ff39557e 100644 --- a/play.pokemonshowdown.com/src/battle-dex-search.ts +++ b/play.pokemonshowdown.com/src/battle-dex-search.ts @@ -639,10 +639,8 @@ abstract class BattleTypedSearch { this.dex = Dex.mod('gen7letsgo' as ID); } if (format.includes('nationaldex') || format.startsWith('nd') || format.includes('natdex')) { - if (format !== 'nationaldexdoubles') { - format = (format.startsWith('nd') ? format.slice(2) : - format.includes('natdex') ? format.slice(6) : format.slice(11)) as ID; - } + format = (format.startsWith('nd') ? format.slice(2) : + format.includes('natdex') ? format.slice(6) : format.slice(11)) as ID; this.formatType = 'natdex'; if (!format) format = 'ou' as ID; } @@ -1085,12 +1083,18 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { return true; }); } - if (format === 'nationaldexdoubles' && table.ndDoublesBans) { + if (format === 'doubles' && this.formatType === 'natdex' && table.ndDoublesBans) { tierSet = tierSet.filter(([type, id]) => { if (id in table.ndDoublesBans) return false; return true; }); } + if (format === '35pokes' && table.thirtyfivePokes) { + tierSet = tierSet.filter(([type, id]) => { + if (id in table.thirtyfivePokes) return true; + return false; + }); + } if (dex.gen >= 5) { if ((format === 'monotype' || format.startsWith('monothreat')) && table.monotypeBans) { tierSet = tierSet.filter(([type, id]) => { From f8b890e543f88752aba924c56b4b440ca45d30cf Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Tue, 1 Oct 2024 21:27:15 -0600 Subject: [PATCH 737/770] Remove references to the Section Leader rank --- play.pokemonshowdown.com/js/client.js | 5 ----- play.pokemonshowdown.com/src/client-main.ts | 7 +------ pokemonshowdown.com/pages/staff-ja.md | 2 -- pokemonshowdown.com/pages/staff.md | 2 -- 4 files changed, 1 insertion(+), 15 deletions(-) diff --git a/play.pokemonshowdown.com/js/client.js b/play.pokemonshowdown.com/js/client.js index e4fff3c707..8caa893622 100644 --- a/play.pokemonshowdown.com/js/client.js +++ b/play.pokemonshowdown.com/js/client.js @@ -2682,11 +2682,6 @@ function toId() { type: 'staff', order: 10006 }, - '\u00a7': { - name: "Section Leader (\u00a7)", - type: 'staff', - order: 10007 - }, '*': { name: "Bot (*)", type: 'normal', diff --git a/play.pokemonshowdown.com/src/client-main.ts b/play.pokemonshowdown.com/src/client-main.ts index cb2c9f9baa..8e33e27e23 100644 --- a/play.pokemonshowdown.com/src/client-main.ts +++ b/play.pokemonshowdown.com/src/client-main.ts @@ -363,12 +363,7 @@ class PSServer { type: 'staff', order: 106, }, - '\u00a7': { - name: "Section Leader (\u00a7)", - type: 'staff', - order: 107, - }, - // by default, unrecognized ranks go here, between section leader and bot + // by default, unrecognized ranks go here, between driver and bot '*': { name: "Bot (*)", order: 109, diff --git a/pokemonshowdown.com/pages/staff-ja.md b/pokemonshowdown.com/pages/staff-ja.md index 3e5c6a8479..39df55f6fd 100644 --- a/pokemonshowdown.com/pages/staff-ja.md +++ b/pokemonshowdown.com/pages/staff-ja.md @@ -16,8 +16,6 @@ **Room Owner (`#`)** 上記のほか、ユーザーを@に昇格、署名無しの告知文の作成、Room Introの作成が可能。 -**Section Leader (`§`)** そのセクションのpublicなチャットルームを管理しています。誰が各セクションを管理しているかは、[部屋のリスト](https://www.smogon.com/forums/threads/pok%C3%A9mon-showdown-forum-rules-resources-read-here-first.3570628/#post-6804772)から参照できます。 - **Global Driver (`%`)** チャットルームまたは全体で、ユーザーに警告、7分または60分のミュート、2日または7日のロック、強制的に名前を変更、ステータスメッセージの削除、他のアカウントの確認、全部屋の過去ログの確認が可能。 **Global Moderator (`@`)** 上記のほか、ユーザーをサーバからBAN、IPの確認が可能で、Room Moderatorの全権限も有しています。 diff --git a/pokemonshowdown.com/pages/staff.md b/pokemonshowdown.com/pages/staff.md index 9a4ed03e62..595d3e6378 100644 --- a/pokemonshowdown.com/pages/staff.md +++ b/pokemonshowdown.com/pages/staff.md @@ -16,8 +16,6 @@ Room staff have permissions tied specifically to the room they were promoted in, **Room Owners (`#`)** can do all of the above, as well as promote users to Room Moderator, make unsigned declarations, and set the room introduction. -**Section Leaders (`§`)** oversee public chatrooms within their section. You can refer to the [list of rooms](https://www.smogon.com/forums/threads/pok%C3%A9mon-showdown-forum-rules-resources-read-here-first.3570628/#post-6804772) to see who oversees each section. - **Global Drivers (`%`)** can warn users both in rooms and globally, mute users for 7 or 60 minutes, lock users from talking for 2 days or a week, forcibly rename users, clear users' statuses, check users' alternate accounts, check logs of past chat and moderation actions in all rooms. **Global Moderators (`@`)** can do all of the above, as well as ban users from the server, do anything a Room Moderator can do, and check users' IP addresses. From d8eac3b69a80bf19062a043d87085859b0229438 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Fri, 11 Oct 2024 17:04:25 -0600 Subject: [PATCH 738/770] Fix Aegislash's Stance Change animation --- play.pokemonshowdown.com/src/battle-animations.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index 4d570d3edc..cbc70486a9 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -2550,7 +2550,8 @@ export class PokemonSprite extends Sprite { BattleOtherAnims.schoolingin.anim(scene, [this]); } else if (speciesid === 'wishiwashi') { BattleOtherAnims.schoolingout.anim(scene, [this]); - } else if (speciesid === 'mimikyubusted' || speciesid === 'mimikyubustedtotem') { + } else if (speciesid === 'mimikyubusted' || speciesid === 'mimikyubustedtotem' || + speciesid === 'aegislash' || speciesid === 'aegislashblade') { // standard animation } else if (speciesid === 'palafinhero') { skipAnim = true; From c1ced5dbe38ed1ea1ee71158861a9b5bc31ca9f6 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Fri, 18 Oct 2024 00:29:44 +0000 Subject: [PATCH 739/770] Update Privacy Policy for new ad company --- build-tools/update | 2 +- pokemonshowdown.com/pages/privacy.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build-tools/update b/build-tools/update index 4d99acd89d..23d52a8940 100755 --- a/build-tools/update +++ b/build-tools/update @@ -202,7 +202,7 @@ try { let indexContentsOld = indexContents; indexContents = indexContents.replace(//g, '' + fs.readFileSync('config/head-custom.html')); indexContents2 = indexContentsOld.replace(//g, '' + fs.readFileSync('config/head-custom-test.html')); - indexContents2 = indexContents2.replace(/src="\/\/play.pokemonshowdown.com\/config\/config.js\?[a-z0-9]*"/, 'src="//play.pokemonshowdown.com/config/config-test.js?3"'); + indexContents2 = indexContents2.replace(/src="\/\/play.pokemonshowdown.com\/config\/config.js\?[a-z0-9]*"/, 'src="//play.pokemonshowdown.com/config/config-test.js?4"'); } catch (e) {} fs.writeFileSync('play.pokemonshowdown.com/index.html', indexContents); diff --git a/pokemonshowdown.com/pages/privacy.md b/pokemonshowdown.com/pages/privacy.md index 116885cd9b..d0c6c30268 100644 --- a/pokemonshowdown.com/pages/privacy.md +++ b/pokemonshowdown.com/pages/privacy.md @@ -22,9 +22,9 @@ Pokémon Showdown uses Google Analytics and Google AdSense, which collect referr Google has [a page that lets you opt out of AdSense-related tracking](https://www.google.com/settings/ads/onweb/). -## Ads from Enthusiast Gaming +## Ads from Playwire -We show advertisements from Enthusiast Gaming. See [Enthusiast Gaming's privacy policy](https://www.enthusiastgaming.com/privacy-policy/). +We show advertisements from Playwire. All or partial advertising on this Website or App is managed by Playwire LLC. If Playwire publisher advertising services are used, Playwire LLC may collect and use certain aggregated and anonymized data for advertising purposes. To learn more about the types of data collected, how data is used and your choices as a user, please visit [https://www.playwire.com/privacy-policy](https://www.playwire.com/privacy-policy). ## Logging From 8737e397ae4ca3734a0ec89dcf03692063057598 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Fri, 18 Oct 2024 02:08:27 +0000 Subject: [PATCH 740/770] Update Google log-in API Previous one was deprecated and being phased out. --- play.pokemonshowdown.com/js/client-topbar.js | 47 +++----------------- 1 file changed, 6 insertions(+), 41 deletions(-) diff --git a/play.pokemonshowdown.com/js/client-topbar.js b/play.pokemonshowdown.com/js/client-topbar.js index ed2d8dab1b..0aa787b222 100644 --- a/play.pokemonshowdown.com/js/client-topbar.js +++ b/play.pokemonshowdown.com/js/client-topbar.js @@ -1099,7 +1099,8 @@ buf += '

    If this is your account:

    '; buf += '

    '; if (data.special === '@gmail') { - buf += '
    [loading Google log-in button]
    '; + buf += '
    '; + buf += ''; buf += '

    '; } else { buf += '

    '; @@ -1115,50 +1116,14 @@ if (data.special === '@gmail') { var self = this; - window.gapiRenderButton = function () { - if (!window.gapiAuthenticated) { - gapi.load('auth2', function () { // eslint-disable-line no-undef - window.gapiAuthenticated = gapi.auth2.init({ // eslint-disable-line no-undef - client_id: '912270888098-jjnre816lsuhc5clj3vbcn4o2q7p4qvk.apps.googleusercontent.com', - }); - window.gapiAuthenticated.then(function () { - window.gapiAuthenticated = true; - window.gapiRenderButton(); - }); - }); - return; - } - // they're trying again in a new popup, set a new .then so it still works - if (window.gapiAuthenticated.then) { - window.gapiAuthenticated.then(function () { - window.gapiAuthenticated = true; - window.gapiRenderButton(); - }); - return; - } - gapi.signin2.render('gapi-custom-signin', { // eslint-disable-line no-undef - 'scope': 'profile email', - 'width': 240, - 'height': 50, - 'longtitle': true, - 'theme': 'dark', - 'onsuccess': function (googleUser) { - // var profile = googleUser.getBasicProfile(); - var id_token = googleUser.getAuthResponse().id_token; - self.close(); - app.user.passwordRename(data.username, id_token, data.special); - }, - 'onfailure': function (googleUser) { - alert('sign-in failed'); - } - }); + window.gapiCallback = function (response) { + app.user.passwordRename(data.username, response.credential, data.special); + self.close(); }; - if (window.gapiLoaded) return setTimeout(window.gapiRenderButton, 100); - window.gapiLoaded = true; var script = document.createElement('script'); script.async = true; - script.src = 'https://apis.google.com/js/platform.js?onload=gapiRenderButton'; + script.src = 'https://accounts.google.com/gsi/client'; document.getElementsByTagName('head')[0].appendChild(script); } }, From aeecc55b3e4a19b6ccd0ae2e2c930122a9384121 Mon Sep 17 00:00:00 2001 From: shrianshChari <30420527+shrianshChari@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:01:02 -0400 Subject: [PATCH 741/770] Create Burning Bulwark animation (#2293) --- .../src/battle-animations-moves.ts | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/src/battle-animations-moves.ts b/play.pokemonshowdown.com/src/battle-animations-moves.ts index a54122b02c..46efefcf92 100644 --- a/play.pokemonshowdown.com/src/battle-animations-moves.ts +++ b/play.pokemonshowdown.com/src/battle-animations-moves.ts @@ -2623,7 +2623,45 @@ export const BattleMoveAnims: AnimTable = { anim: BattleOtherAnims.selfstatus.anim, }, burningbulwark: { - anim: BattleOtherAnims.selfstatus.anim, + anim(scene, [attacker]) { + scene.backgroundEffect('linear-gradient(#390000 30%, #000000)', 600, 0.2); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y - 30, + z: attacker.z, + scale: 0.5, + xscale: 0.25, + yscale: 0.75, + opacity: 0.5, + }, { + scale: 2, + xscale: 3.5, + opacity: 0.1, + time: 500, + }, 'decel', 'fade'); + scene.showEffect('flareball', { + x: attacker.x, + y: attacker.y - 15, + z: attacker.z, + opacity: 0.5, + scale: 1.5, + }, { + scale: 1.8, + opacity: 0.1, + time: 500, + }, 'decel', 'fade'); + scene.showEffect('poisonwisp', { + x: attacker.x, + y: attacker.y - 15, + z: attacker.z, + opacity: 1, + scale: 3, + }, { + scale: 1.8, + opacity: 0.5, + time: 500, + }, 'decel', 'fade', {filter: 'hue-rotate(90deg)'}); + }, }, banefulbunker: { anim(scene, [attacker]) { From c81a75014e1e6350a08f3ef843115c2136a3169b Mon Sep 17 00:00:00 2001 From: shrianshChari <30420527+shrianshChari@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:01:31 -0400 Subject: [PATCH 742/770] Add animation for Tera Starstorm (#2292) --- .../src/battle-animations-moves.ts | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/play.pokemonshowdown.com/src/battle-animations-moves.ts b/play.pokemonshowdown.com/src/battle-animations-moves.ts index 46efefcf92..cc009246a4 100644 --- a/play.pokemonshowdown.com/src/battle-animations-moves.ts +++ b/play.pokemonshowdown.com/src/battle-animations-moves.ts @@ -36218,6 +36218,151 @@ export const BattleMoveAnims: AnimTable = { }, 'swing'); }, }, + terastarstorm: { + anim(scene, [attacker, ...defenders]) { + scene.backgroundEffect('#000000', 900, 0.5); + + scene.showEffect('iceball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 0.75, + opacity: 0.6, + }, { + x: attacker.x, + y: attacker.y + 200, + z: attacker.z, + scale: 1.25, + opacity: 0, + time: 200, + }, 'decel', '', {filter: 'hue-rotate(0deg)'}); + scene.showEffect('wisp', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 1, + opacity: 0.6, + }, { + x: attacker.x, + y: attacker.y + 200, + z: attacker.z, + scale: 1.5, + opacity: 0, + time: 200, + }, 'decel'); + + for (let defender of defenders) { + let xstep = (defender.x - attacker.x) / 6; + let ystep = (defender.y - 200 - attacker.y) / 6; + let zstep = (defender.z - attacker.z) / 6; + + for (let i = 0; i < 6; i++) { + scene.showEffect('electroball', { + x: attacker.x + xstep * (i + 1), + y: (attacker.y + 200) + ystep * (i + 1), + z: attacker.z + zstep * (i + 1), + scale: 0.7, + opacity: 0.6, + time: 40 * i + 300, + }, { + opacity: 0, + time: 100 * i + 500, + }, 'linear', '', {filter: `hue-rotate(${60 * i + 30}deg)`}); + } + + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y + 200, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 300, + }, { + x: defender.x + 30, + y: defender.y + 30, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 500, + }, 'linear', 'explode', {filter: 'hue-rotate(30deg)'}); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y + 200, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 375, + }, { + x: defender.x + 20, + y: defender.y - 30, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 575, + }, 'linear', 'explode', {filter: 'hue-rotate(90deg)'}); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y + 200, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 425, + }, { + x: defender.x - 10, + y: defender.y + 10, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 625, + }, 'linear', 'explode', {filter: 'hue-rotate(150deg)'}); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y + 200, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 450, + }, { + x: defender.x - 30, + y: defender.y, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 650, + }, 'linear', 'explode', {filter: 'hue-rotate(210deg)'}); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y + 200, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 500, + }, { + x: defender.x + 10, + y: defender.y - 10, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 700, + }, 'linear', 'explode', {filter: 'hue-rotate(270deg)'}); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y + 200, + z: attacker.z, + scale: 0.4, + opacity: 0.6, + time: 575, + }, { + x: defender.x - 20, + y: defender.y, + z: defender.z, + scale: 0.6, + opacity: 0.3, + time: 775, + }, 'linear', 'explode', {filter: 'hue-rotate(330deg)'}); + } + }, + }, }; // placeholder animations From 41228a5942a2bd7ce6ffa635393c4fa1b1ad1fdd Mon Sep 17 00:00:00 2001 From: shrianshChari <30420527+shrianshChari@users.noreply.github.com> Date: Sat, 26 Oct 2024 10:59:30 -0400 Subject: [PATCH 743/770] Add animation for Thunderclap (#2294) * Add animation for Thunderclap * Add sparks before Thunderclap bolt * Satisfy linter --- .../src/battle-animations-moves.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/play.pokemonshowdown.com/src/battle-animations-moves.ts b/play.pokemonshowdown.com/src/battle-animations-moves.ts index cc009246a4..f80971cb8b 100644 --- a/play.pokemonshowdown.com/src/battle-animations-moves.ts +++ b/play.pokemonshowdown.com/src/battle-animations-moves.ts @@ -36363,6 +36363,36 @@ export const BattleMoveAnims: AnimTable = { } }, }, + thunderclap: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('#000000', 200, 0.2); + scene.showEffect('electroball', { + x: attacker.x, + y: attacker.y, + z: attacker.z, + scale: 1.5, + opacity: 0.8, + }, { + scale: 3, + opacity: 0.2, + time: 200, + }, 'accel', 'fade', {filter: 'hue-rotate(150deg)'}); + scene.showEffect('lightning', { + x: defender.x, + y: defender.y + 150, + z: defender.z, + yscale: 0, + xscale: 2, + time: 200, + }, { + y: defender.y + 50, + yscale: 1, + xscale: 1.5, + opacity: 0.8, + time: 400, + }, 'linear', 'fade', {filter: 'hue-rotate(180deg)'}); + }, + }, }; // placeholder animations From cd9f9508f880b921799ee1d591fc5d0db9d19de3 Mon Sep 17 00:00:00 2001 From: Marty-D Date: Sun, 27 Oct 2024 09:06:47 -0400 Subject: [PATCH 744/770] Teambuilder: Use battle sprites for dex sprite-less Pokemon --- play.pokemonshowdown.com/src/battle-dex.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/src/battle-dex.ts b/play.pokemonshowdown.com/src/battle-dex.ts index 33065186f6..e45aacc0f7 100644 --- a/play.pokemonshowdown.com/src/battle-dex.ts +++ b/play.pokemonshowdown.com/src/battle-dex.ts @@ -764,7 +764,7 @@ const Dex = new class implements ModdedDex { let xydexExists = (!species.isNonstandard || species.isNonstandard === 'Past' || species.isNonstandard === 'CAP') || [ "pikachustarter", "eeveestarter", "meltan", "melmetal", "pokestarufo", "pokestarufo2", "pokestarbrycenman", "pokestarmt", "pokestarmt2", "pokestargiant", "pokestarhumanoid", "pokestarmonster", "pokestarf00", "pokestarf002", "pokestarspirit", ].includes(species.id); - if (species.gen === 8 && species.isNonstandard !== 'CAP') xydexExists = false; + if (species.gen >= 8 && species.isNonstandard !== 'CAP') xydexExists = false; if ((!gen || gen >= 6) && xydexExists) { if (species.gen >= 7) { spriteData.x = -6; From 12217562944e7ff9e14c03149ab4854744757973 Mon Sep 17 00:00:00 2001 From: Mia <49593536+mia-pi-git@users.noreply.github.com> Date: Fri, 1 Nov 2024 13:31:22 -0500 Subject: [PATCH 745/770] Display suspect test eligibility in /rank --- play.pokemonshowdown.com/js/client-chat.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/play.pokemonshowdown.com/js/client-chat.js b/play.pokemonshowdown.com/js/client-chat.js index 62c683e07a..26aa49b734 100644 --- a/play.pokemonshowdown.com/js/client-chat.js +++ b/play.pokemonshowdown.com/js/client-chat.js @@ -978,8 +978,13 @@ buffer += ''; return self.add('|raw|' + buffer); } - buffer += 'FormatEloGXEGlicko-1COILWLTotal'; - + buffer += 'FormatEloGXEGlicko-1COILWLTotal'; + var suspect = false; + for (var i = 0; i < data.length; i++) { + if ('suspect' in data[i]) suspect = true; + } + if (suspect) buffer += 'Suspect test eligible?'; + buffer += ''; var hiddenFormats = []; for (var i = 0; i < data.length; i++) { var row = data[i]; @@ -1015,7 +1020,17 @@ } else { buffer += '--'; } - buffer += '' + row.w + '' + row.l + '' + N + ''; + buffer += '' + row.w + '' + row.l + '' + N + ''; + if (suspect) { + if (typeof row.suspect === 'undefined') { + buffer += '--'; + } else { + buffer += ''; + buffer += (row.suspect ? "Yes" : "No"); + buffer += ''; + } + } + buffer += ''; } if (hiddenFormats.length) { if (hiddenFormats.length === data.length) { From 06c097fe8aa13ef3babba7f505300a015f5fb464 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:38:08 -0700 Subject: [PATCH 746/770] Teambuilder: Remove ADV RU hardcode --- play.pokemonshowdown.com/src/battle-dex-search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/src/battle-dex-search.ts b/play.pokemonshowdown.com/src/battle-dex-search.ts index a9ff39557e..8cf283b9c3 100644 --- a/play.pokemonshowdown.com/src/battle-dex-search.ts +++ b/play.pokemonshowdown.com/src/battle-dex-search.ts @@ -1041,7 +1041,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { }); } } else if (format === 'ou') tierSet = tierSet.slice(slices.OU); - else if (format === 'uu' || (format === 'ru' && dex.gen === 3)) tierSet = tierSet.slice(slices.UU); + else if (format === 'uu') tierSet = tierSet.slice(slices.UU); else if (format === 'ru') tierSet = tierSet.slice(slices.RU || slices.UU); else if (format === 'nu') tierSet = tierSet.slice(slices.NU || slices.RU || slices.UU); else if (format === 'pu') tierSet = tierSet.slice(slices.PU || slices.NU); From acd0d999bba270d27e30cf5bea155d905d1b4e81 Mon Sep 17 00:00:00 2001 From: shrianshChari <30420527+shrianshChari@users.noreply.github.com> Date: Tue, 5 Nov 2024 00:47:07 -0500 Subject: [PATCH 747/770] Add animation for Mighty Cleave (#2295) * Mighty Cleave animation first draft * Give the slash a big streak --- .../src/battle-animations-moves.ts | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/play.pokemonshowdown.com/src/battle-animations-moves.ts b/play.pokemonshowdown.com/src/battle-animations-moves.ts index f80971cb8b..72c4c62151 100644 --- a/play.pokemonshowdown.com/src/battle-animations-moves.ts +++ b/play.pokemonshowdown.com/src/battle-animations-moves.ts @@ -36393,6 +36393,81 @@ export const BattleMoveAnims: AnimTable = { }, 'linear', 'fade', {filter: 'hue-rotate(180deg)'}); }, }, + mightycleave: { + anim(scene, [attacker, defender]) { + scene.showEffect('sword', { + x: attacker.leftof(-10), + y: attacker.y - 10, + z: attacker.z, + scale: 0.5, + opacity: 1, + }, { + y: attacker.y + 10, + scale: 1, + opacity: 0.4, + time: 300, + }, 'decel', 'fade'); + attacker.delay(300); + attacker.anim({ + x: defender.x, + y: defender.y, + z: defender.behind(70), + time: 300, + opacity: 0.5, + }, 'accel'); + attacker.anim({ + x: defender.x, + y: defender.x, + z: defender.behind(100), + opacity: 0, + time: 100, + }, 'linear'); + attacker.anim({ + x: attacker.x, + y: attacker.y, + z: attacker.behind(70), + opacity: 0, + time: 1, + }, 'linear'); + attacker.anim({ + opacity: 1, + time: 500, + }, 'decel'); + scene.showEffect('iceball', { + x: defender.x, + y: defender.y, + z: defender.z, + time: 500, + xscale: 1.2, + yscale: 0.4, + opacity: 0.8, + }, { + time: 760, + xscale: 1.4, + yscale: 0.6, + opacity: 0.4, + }, 'accel', 'explode', {filter: 'hue-rotate(180deg)', rotate: '-45deg'}); + scene.showEffect('rightslash', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 1.5, + time: 500, + }, { + scale: 2, + opacity: 0, + time: 760, + }, 'accel', 'fade'); + defender.delay(760); + defender.anim({ + z: defender.behind(30), + time: 100, + }, 'swing'); + defender.anim({ + time: 300, + }, 'swing'); + }, + }, }; // placeholder animations From 878464aec735901fb2f15bf46120113fdfac8c73 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Tue, 5 Nov 2024 16:16:40 -0700 Subject: [PATCH 748/770] `/rank`: Fix colspan spacing --- play.pokemonshowdown.com/js/client-chat.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/play.pokemonshowdown.com/js/client-chat.js b/play.pokemonshowdown.com/js/client-chat.js index 26aa49b734..d16e4b473d 100644 --- a/play.pokemonshowdown.com/js/client-chat.js +++ b/play.pokemonshowdown.com/js/client-chat.js @@ -972,9 +972,9 @@ user: targets[0] }, Storage.safeJSON(function (data) { if (!data || !$.isArray(data)) return self.add('|raw|Error: corrupted ranking data'); - var buffer = '
    '; + var buffer = '
    User: ' + toName(targets[0]) + '
    '; if (!data.length) { - buffer += ''; + buffer += ''; buffer += '
    User: ' + toName(targets[0]) + '
    This user has not played any ladder games yet.
    This user has not played any ladder games yet.
    '; return self.add('|raw|' + buffer); } From 1ff6525035b689e8cdab2db227dc540a270661f6 Mon Sep 17 00:00:00 2001 From: "Alex \"Mathy" <4866817+MathyFurret@users.noreply.github.com> Date: Wed, 6 Nov 2024 23:45:34 -0600 Subject: [PATCH 749/770] Account for Morpeko form permanence (#2297) * Account for Morpeko form permanence * Update play.pokemonshowdown.com/src/battle.ts --------- Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com> --- play.pokemonshowdown.com/src/battle.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index 4a9b73e9af..053b5c4e6d 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -2523,6 +2523,10 @@ export class Battle { poke.terastallized = type; poke.details += `, tera:${type}`; poke.searchid += `, tera:${type}`; + if (poke.speciesForme.startsWith("Morpeko")) { + poke.details = poke.details.replace("Morpeko", poke.speciesForme); + poke.searchid = `${poke.ident}|${poke.details}`; + } this.scene.animTransform(poke, true); this.scene.resetStatbar(poke); this.log(args, kwArgs); From 9a9728b13952717c5e7d1d6aa219562bdbf5256d Mon Sep 17 00:00:00 2001 From: shrianshChari <30420527+shrianshChari@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:43:11 -0500 Subject: [PATCH 750/770] Modify animation for Spirit Break (#2298) --- .../src/battle-animations-moves.ts | 91 ++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/src/battle-animations-moves.ts b/play.pokemonshowdown.com/src/battle-animations-moves.ts index 72c4c62151..4ee7fd2cce 100644 --- a/play.pokemonshowdown.com/src/battle-animations-moves.ts +++ b/play.pokemonshowdown.com/src/battle-animations-moves.ts @@ -36468,6 +36468,96 @@ export const BattleMoveAnims: AnimTable = { }, 'swing'); }, }, + spiritbreak: { + anim(scene, [attacker, defender]) { + scene.backgroundEffect('#000000', 1000, 0.3); + + scene.showEffect('mistball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.4, + time: 425, + opacity: 0.2, + }, { + scale: 0.6, + time: 750, + opacity: 1, + }, 'decel', 'fade'); + scene.showEffect('mistball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.6, + time: 750, + opacity: 1, + }, { + time: 1000, + scale: 2.5, + opacity: 0.2, + }, 'decel', 'explode'); + + scene.showEffect('iceball', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 2, + time: 850, + opacity: 0.4, + }, { + time: 1000, + scale: 3, + opacity: 0.1, + }, 'decel', 'explode'); + + scene.showEffect('shine', { + x: defender.x, + y: defender.y, + z: defender.z, + time: 750, + scale: 0.8, + }, { + opacity: 0.4, + time: 800, + }, 'decel', 'explode', {filter: 'invert(1)'}); + scene.showEffect('impact', { + x: defender.x, + y: defender.y, + z: defender.z, + time: 875, + scale: 0.8, + }, { + opacity: 0.4, + time: 925, + }, 'decel', 'explode', {filter: 'brightness(50%)'}); + + attacker.anim({ + x: defender.leftof(20), + y: defender.y, + z: defender.behind(-20), + time: 400, + }, 'ballistic2Under'); + attacker.anim({ + x: defender.x, + y: defender.y, + z: defender.z, + time: 50, + }); + attacker.anim({ + time: 500, + }, 'ballistic2'); + defender.delay(750); + defender.anim({ + x: defender.leftof(15), + y: defender.y, + z: defender.behind(20), + time: 50, + }, 'swing'); + defender.anim({ + time: 200, + }, 'swing'); + }, + }, }; // placeholder animations @@ -36791,7 +36881,6 @@ BattleMoveAnims['branchpoke'] = {anim: BattleMoveAnims['vinewhip'].anim}; BattleMoveAnims['overdrive'] = {anim: BattleMoveAnims['discharge'].anim}; BattleMoveAnims['appleacid'] = {anim: BattleMoveAnims['energyball'].anim}; BattleMoveAnims['gravapple'] = {anim: BattleMoveAnims['energyball'].anim}; -BattleMoveAnims['spiritbreak'] = {anim: BattleMoveAnims['moonblast'].anim}; BattleMoveAnims['obstruct'] = {anim: BattleMoveAnims['kingsshield'].anim}; BattleMoveAnims['maxguard'] = {anim: BattleMoveAnims['banefulbunker'].anim}; BattleMoveAnims['falsesurrender'] = {anim: BattleMoveAnims['feintattack'].anim}; From 6e29f5df66ee5e9e0b2cca5cb724b2490a8e0236 Mon Sep 17 00:00:00 2001 From: Christopher Monsanto Date: Tue, 12 Nov 2024 09:25:06 -0500 Subject: [PATCH 751/770] Chat: different wording for suspect test eligible --- play.pokemonshowdown.com/js/client-chat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/js/client-chat.js b/play.pokemonshowdown.com/js/client-chat.js index d16e4b473d..fb4da9d3ed 100644 --- a/play.pokemonshowdown.com/js/client-chat.js +++ b/play.pokemonshowdown.com/js/client-chat.js @@ -983,7 +983,7 @@ for (var i = 0; i < data.length; i++) { if ('suspect' in data[i]) suspect = true; } - if (suspect) buffer += 'Suspect test eligible?'; + if (suspect) buffer += 'Suspect reqs possible?'; buffer += ''; var hiddenFormats = []; for (var i = 0; i < data.length; i++) { From 5706935740cf88d1e25b1df8556a76f47a299634 Mon Sep 17 00:00:00 2001 From: shrianshChari <30420527+shrianshChari@users.noreply.github.com> Date: Tue, 12 Nov 2024 20:30:17 -0500 Subject: [PATCH 752/770] Modify animation for Stone Axe (#2299) --- .../src/battle-animations-moves.ts | 72 +++++++++++++++++-- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-animations-moves.ts b/play.pokemonshowdown.com/src/battle-animations-moves.ts index 4ee7fd2cce..6f02d17059 100644 --- a/play.pokemonshowdown.com/src/battle-animations-moves.ts +++ b/play.pokemonshowdown.com/src/battle-animations-moves.ts @@ -36558,6 +36558,72 @@ export const BattleMoveAnims: AnimTable = { }, 'swing'); }, }, + stoneaxe: { + anim(scene, [attacker, defender]) { + BattleOtherAnims.slashattack.anim(scene, [attacker, defender]); + + scene.showEffect('rock1', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.1, + opacity: 0.5, + time: 500, + }, { + x: defender.x - 30, + y: defender.y + 15, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 800, + }, 'ballistic', 'fade'); + scene.showEffect('rock3', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.1, + opacity: 0.5, + time: 500, + }, { + x: defender.x + 36, + y: defender.y + 45, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 800, + }, 'ballistic', 'fade'); + scene.showEffect('rock2', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.1, + opacity: 0.5, + time: 500, + }, { + x: defender.x + 40, + y: defender.y - 25, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 800, + }, 'ballistic', 'fade'); + scene.showEffect('rock3', { + x: defender.x, + y: defender.y, + z: defender.z, + scale: 0.1, + opacity: 0.5, + time: 500, + }, { + x: defender.x - 20, + y: defender.y - 25, + z: defender.z, + scale: 0.2, + opacity: 1, + time: 800, + }, 'ballistic', 'fade'); + }, + }, }; // placeholder animations @@ -36932,12 +36998,6 @@ BattleMoveAnims['ragefist'] = {anim: BattleMoveAnims['shadowpunch'].anim}; BattleMoveAnims['ragingbull'] = {anim: BattleMoveAnims['gigaimpact'].anim}; BattleMoveAnims['shedtail'] = {anim: BattleMoveAnims['substitute'].anim}; BattleMoveAnims['shelter'] = {anim: BattleMoveAnims['withdraw'].anim}; -BattleMoveAnims['stoneaxe'] = { - anim(scene, [attacker, defender]) { - BattleMoveAnims['stoneedge'].anim(scene, [attacker, defender]); - BattleOtherAnims.slashattack.anim(scene, [attacker, defender]); - }, -}; BattleMoveAnims['terablast'] = {anim: BattleMoveAnims['scald'].anim}; BattleMoveAnims['terablastbug'] = {anim: BattleMoveAnims['bugbuzz'].anim}; BattleMoveAnims['terablastdark'] = {anim: BattleMoveAnims['darkpulse'].anim}; From c32f5e261e8dcd9bbcec3d108218912255d5599d Mon Sep 17 00:00:00 2001 From: Sean <34076225+Rezzo64@users.noreply.github.com> Date: Wed, 13 Nov 2024 01:31:15 +0000 Subject: [PATCH 753/770] ADV: Update move viability categories (#2288) * gen 3 useful + useless moves update * moveIsNotUseless: disambiguate OR operation --- .../src/battle-dex-search.ts | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-dex-search.ts b/play.pokemonshowdown.com/src/battle-dex-search.ts index 8cf283b9c3..ab5f21c32c 100644 --- a/play.pokemonshowdown.com/src/battle-dex-search.ts +++ b/play.pokemonshowdown.com/src/battle-dex-search.ts @@ -1413,7 +1413,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return abilityid !== 'sheerforce'; case 'solarbeam': case 'solarblade': return ['desolateland', 'drought', 'chlorophyll', 'orichalcumpulse'].includes(abilityid) || itemid === 'powerherb'; - case 'dynamicpunch': case 'grasswhistle': case 'inferno': case 'sing': case 'zapcannon': + case 'dynamicpunch': case 'grasswhistle': case 'inferno': case 'sing': return abilityid === 'noguard'; case 'heatcrash': case 'heavyslam': return species.weightkg >= (species.evos ? 75 : 130); @@ -1446,6 +1446,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return true; case 'feint': return abilityid === 'refrigerate'; + case 'futuresight': + return dex.gen > 5; case 'grassyglide': return abilityid === 'grassysurge'; case 'gyroball': @@ -1462,7 +1464,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return (dex.gen < 4 && !moves.includes('firepunch')) && !moves.includes('flamethrower') && !moves.includes('mysticalfire') && !moves.includes('burningjealousy'); case 'hiddenpowergrass': - return !moves.includes('energyball') && !moves.includes('grassknot') && !moves.includes('gigadrain'); + return (dex.gen < 4 && !moves.includes('leafblade')) || + (dex.gen > 3 && !moves.includes('energyball') && !moves.includes('grassknot') && !moves.includes('gigadrain')); case 'hiddenpowerice': return !moves.includes('icebeam') && (dex.gen < 4 && !moves.includes('icepunch')) || (dex.gen > 5 && !moves.includes('aurorabeam') && !moves.includes('glaciate')); @@ -1480,6 +1483,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return !moves.includes('icespinner') || ['sheerforce', 'ironfist'].includes(abilityid) || itemid === 'punchingglove'; case 'iciclecrash': return !moves.includes('mountaingale'); + case 'iciclespear': + return dex.gen > 3; case 'icywind': // Keldeo needs Hidden Power for Electric/Ghost return species.baseSpecies === 'Keldeo' || this.formatType === 'doubles'; @@ -1493,24 +1498,32 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return !moves.includes('highjumpkick') && !moves.includes('axekick'); case 'lastresort': return set && set.moves.length < 3; + case 'leafblade': + return dex.gen < 4; case 'leechlife': return dex.gen > 6; + case 'magiccoat': + return dex.gen > 3; case 'meteorbeam': return true; case 'mysticalfire': return dex.gen > 6 && !moves.includes('flamethrower'); case 'naturepower': return dex.gen === 5; + case 'needlearm': + return dex.gen < 4; case 'nightslash': return !moves.includes('crunch') && !(moves.includes('knockoff') && dex.gen >= 6); case 'outrage': - return !moves.includes('glaiverush'); + return dex.gen > 3 && !moves.includes('glaiverush'); case 'petaldance': return abilityid === 'owntempo'; case 'phantomforce': return (!moves.includes('poltergeist') && !moves.includes('shadowclaw')) || this.formatType === 'doubles'; case 'poisonfang': return species.types.includes('Poison') && !moves.includes('gunkshot') && !moves.includes('poisonjab'); + case 'raindance': + return dex.gen < 4; case 'relicsong': return species.id === 'meloetta'; case 'refresh': @@ -1525,6 +1538,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return abilityid === 'ironfist' && !moves.includes('ragefist'); case 'shelter': return !moves.includes('acidarmor') && !moves.includes('irondefense'); + case 'skyuppercut': + return dex.gen < 4; case 'smackdown': return species.types.includes('Ground'); case 'smartstrike': @@ -1537,6 +1552,8 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return (!moves.includes('earthquake') && !moves.includes('drillrun')) || this.formatType === 'doubles'; case 'stunspore': return !moves.includes('thunderwave'); + case 'sunnyday': + return dex.gen < 4; case 'technoblast': return dex.gen > 5 && itemid.endsWith('drive') || itemid === 'dousedrive'; case 'teleport': @@ -1550,10 +1567,14 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { return dex.gen === 2; case 'toxicspikes': return abilityid !== 'toxicdebris'; + case 'triattack': + return dex.gen > 3; case 'trickroom': return species.baseStats.spe <= 100; case 'wildcharge': return !moves.includes('supercellslam'); + case 'zapcannon': + return abilityid === 'noguard' || (dex.gen < 4 && !moves.includes('thunderwave')); } if (this.formatType === 'doubles' && BattleMoveSearch.GOOD_DOUBLES_MOVES.includes(id)) { @@ -1588,10 +1609,10 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { 'acidarmor', 'agility', 'aromatherapy', 'auroraveil', 'autotomize', 'banefulbunker', 'batonpass', 'bellydrum', 'bulkup', 'burningbulwark', 'calmmind', 'chillyreception', 'clangoroussoul', 'coil', 'cottonguard', 'courtchange', 'curse', 'defog', 'destinybond', 'detect', 'disable', 'dragondance', 'encore', 'extremeevoboost', 'filletaway', 'geomancy', 'glare', 'haze', 'healbell', 'healingwish', 'healorder', 'heartswap', 'honeclaws', 'kingsshield', 'leechseed', 'lightscreen', 'lovelykiss', 'lunardance', 'magiccoat', 'maxguard', 'memento', 'milkdrink', 'moonlight', 'morningsun', 'nastyplot', 'naturesmadness', 'noretreat', 'obstruct', 'painsplit', 'partingshot', 'perishsong', 'protect', 'quiverdance', 'recover', 'reflect', 'reflecttype', 'rest', 'revivalblessing', 'roar', 'rockpolish', 'roost', 'shedtail', 'shellsmash', 'shiftgear', 'shoreup', 'silktrap', 'slackoff', 'sleeppowder', 'sleeptalk', 'softboiled', 'spikes', 'spikyshield', 'spore', 'stealthrock', 'stickyweb', 'strengthsap', 'substitute', 'switcheroo', 'swordsdance', 'synthesis', 'tailglow', 'tailwind', 'taunt', 'thunderwave', 'tidyup', 'toxic', 'transform', 'trick', 'victorydance', 'whirlwind', 'willowisp', 'wish', 'yawn', ] as ID[] as readonly ID[]; static readonly GOOD_WEAK_MOVES = [ - 'accelerock', 'acrobatics', 'aquacutter', 'avalanche', 'barbbarrage', 'bonemerang', 'bouncybubble', 'bulletpunch', 'buzzybuzz', 'ceaselessedge', 'circlethrow', 'clearsmog', 'doubleironbash', 'dragondarts', 'dragontail', 'drainingkiss', 'endeavor', 'facade', 'firefang', 'flipturn', 'flowertrick', 'freezedry', 'frustration', 'geargrind', 'grassknot', 'gyroball', 'icefang', 'iceshard', 'iciclespear', 'infernalparade', 'knockoff', 'lastrespects', 'lowkick', 'machpunch', 'mortalspin', 'mysticalpower', 'naturesmadness', 'nightshade', 'nuzzle', 'pikapapow', 'populationbomb', 'psychocut', 'psyshieldbash', 'pursuit', 'quickattack', 'ragefist', 'rapidspin', 'return', 'rockblast', 'ruination', 'saltcure', 'scorchingsands', 'seismictoss', 'shadowclaw', 'shadowsneak', 'sizzlyslide', 'stoneaxe', 'storedpower', 'stormthrow', 'suckerpunch', 'superfang', 'surgingstrikes', 'tachyoncutter', 'tailslap', 'thunderclap', 'tripleaxel', 'tripledive', 'twinbeam', 'uturn', 'veeveevolley', 'voltswitch', 'watershuriken', 'weatherball', + 'accelerock', 'acrobatics', 'aquacutter', 'avalanche', 'barbbarrage', 'bonemerang', 'bouncybubble', 'bulletpunch', 'buzzybuzz', 'ceaselessedge', 'circlethrow', 'clearsmog', 'doubleironbash', 'dragondarts', 'dragontail', 'drainingkiss', 'endeavor', 'facade', 'firefang', 'flipturn', 'flowertrick', 'freezedry', 'frustration', 'geargrind', 'gigadrain', 'grassknot', 'gyroball', 'icefang', 'iceshard', 'iciclespear', 'infernalparade', 'knockoff', 'lastrespects', 'lowkick', 'machpunch', 'mortalspin', 'mysticalpower', 'naturesmadness', 'nightshade', 'nuzzle', 'pikapapow', 'populationbomb', 'psychocut', 'psyshieldbash', 'pursuit', 'quickattack', 'ragefist', 'rapidspin', 'return', 'rockblast', 'ruination', 'saltcure', 'scorchingsands', 'seismictoss', 'shadowclaw', 'shadowsneak', 'sizzlyslide', 'stoneaxe', 'storedpower', 'stormthrow', 'suckerpunch', 'superfang', 'surgingstrikes', 'tachyoncutter', 'tailslap', 'thunderclap', 'tripleaxel', 'tripledive', 'twinbeam', 'uturn', 'veeveevolley', 'voltswitch', 'watershuriken', 'weatherball', ] as ID[] as readonly ID[]; static readonly BAD_STRONG_MOVES = [ - 'belch', 'burnup', 'crushclaw', 'dragonrush', 'dreameater', 'eggbomb', 'firepledge', 'flyingpress', 'grasspledge', 'hyperbeam', 'hyperfang', 'hyperspacehole', 'jawlock', 'landswrath', 'megakick', 'megapunch', 'mistyexplosion', 'muddywater', 'nightdaze', 'pollenpuff', 'rockclimb', 'selfdestruct', 'shelltrap', 'skyuppercut', 'slam', 'strength', 'submission', 'synchronoise', 'takedown', 'thrash', 'uproar', 'waterpledge', + 'belch', 'burnup', 'crushclaw', 'dragonrush', 'dreameater', 'eggbomb', 'firepledge', 'flyingpress', 'futuresight', 'grasspledge', 'hyperbeam', 'hyperfang', 'hyperspacehole', 'jawlock', 'landswrath', 'megakick', 'megapunch', 'mistyexplosion', 'muddywater', 'nightdaze', 'pollenpuff', 'rockclimb', 'selfdestruct', 'shelltrap', 'skyuppercut', 'slam', 'strength', 'submission', 'synchronoise', 'takedown', 'thrash', 'uproar', 'waterpledge', ] as ID[] as readonly ID[]; static readonly GOOD_DOUBLES_MOVES = [ 'allyswitch', 'bulldoze', 'coaching', 'electroweb', 'faketears', 'fling', 'followme', 'healpulse', 'helpinghand', 'junglehealing', 'lifedew', 'lunarblessing', 'muddywater', 'pollenpuff', 'psychup', 'ragepowder', 'safeguard', 'skillswap', 'snipeshot', 'wideguard', From e4c54acc9209acf6e378995e051ea8a72f989985 Mon Sep 17 00:00:00 2001 From: HiZo <96159984+HisuianZoroark@users.noreply.github.com> Date: Mon, 18 Nov 2024 18:10:40 -0500 Subject: [PATCH 754/770] Display exact HP when using Exact HP Mod (#2280) * Display information current and max HP when using Exact HP Mod * why doesnt lint catch this smh --- play.pokemonshowdown.com/src/battle-animations.ts | 2 +- play.pokemonshowdown.com/src/battle-tooltips.ts | 2 +- play.pokemonshowdown.com/src/battle.ts | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index cbc70486a9..d1633213d2 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -2872,7 +2872,7 @@ export class PokemonSprite extends Sprite { if (pokemon.maxhp === 48 || this.scene.battle.hardcoreMode && pokemon.maxhp === 100) { $hptext.hide(); $hptextborder.hide(); - } else if (this.scene.battle.hardcoreMode) { + } else if (this.scene.battle.hardcoreMode || this.scene.battle.reportExactHP) { $hptext.html(pokemon.hp + '/'); $hptext.show(); $hptextborder.show(); diff --git a/play.pokemonshowdown.com/src/battle-tooltips.ts b/play.pokemonshowdown.com/src/battle-tooltips.ts index ebeb171361..814a500751 100644 --- a/play.pokemonshowdown.com/src/battle-tooltips.ts +++ b/play.pokemonshowdown.com/src/battle-tooltips.ts @@ -843,7 +843,7 @@ class BattleTooltips { } else if (pokemon.maxhp === 48) { exacthp = ' (' + pokemon.hp + '/' + pokemon.maxhp + ' pixels)'; } - text += '

    HP: ' + Pokemon.getHPText(pokemon) + exacthp + (pokemon.status ? ' ' + pokemon.status.toUpperCase() + '' : ''); + text += '

    HP: ' + Pokemon.getHPText(pokemon, this.battle.reportExactHP) + exacthp + (pokemon.status ? ' ' + pokemon.status.toUpperCase() + '' : ''); if (clientPokemon) { if (pokemon.status === 'tox') { if (pokemon.ability === 'Poison Heal' || pokemon.ability === 'Magic Guard') { diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index 053b5c4e6d..02c22f8a5f 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -582,9 +582,10 @@ export class Pokemon implements PokemonDetails, PokemonHealth { return percentage * maxWidth / 100; } getHPText(precision = 1) { - return Pokemon.getHPText(this, precision); + return Pokemon.getHPText(this, this.side.battle.reportExactHP, precision); } - static getHPText(pokemon: PokemonHealth, precision = 1) { + static getHPText(pokemon: PokemonHealth, exactHP: boolean, precision = 1) { + if (exactHP) return pokemon.hp + '/' + pokemon.maxhp; if (pokemon.maxhp === 100) return pokemon.hp + '%'; if (pokemon.maxhp !== 48) return (100 * pokemon.hp / pokemon.maxhp).toFixed(precision) + '%'; let range = Pokemon.getPixelRange(pokemon.hp, pokemon.hpcolor); @@ -1097,6 +1098,7 @@ export class Battle { rated: string | boolean = false; rules: {[ruleName: string]: 1 | 0} = {}; isBlitz = false; + reportExactHP = false; endLastTurnPending = false; totalTimeLeft = 0; graceTimeLeft = 0; @@ -3444,6 +3446,7 @@ export class Battle { this.messageFadeTime = 40; this.isBlitz = true; } + if (ruleName === 'Exact HP Mod') this.reportExactHP = true; this.rules[ruleName] = 1; this.log(args); break; From 72d1216e19bad07c17cb0ccd911b457263419f93 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:12:49 -0700 Subject: [PATCH 755/770] Triples: Make Shift button an actual button --- play.pokemonshowdown.com/js/client-battle.js | 7 ++++++- play.pokemonshowdown.com/style/client.css | 5 +++-- play.pokemonshowdown.com/style/client2.css | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/play.pokemonshowdown.com/js/client-battle.js b/play.pokemonshowdown.com/js/client-battle.js index 4313904031..6e2f220f18 100644 --- a/play.pokemonshowdown.com/js/client-battle.js +++ b/play.pokemonshowdown.com/js/client-battle.js @@ -761,7 +761,12 @@ var shiftControls = ''; if (this.battle.gameType === 'triples' && pos !== 1) { - shiftControls += '

    '; + shiftControls = ( + '
    ' + + '
    ' + + '
    ' + + '
    ' + ); } var switchMenu = ''; diff --git a/play.pokemonshowdown.com/style/client.css b/play.pokemonshowdown.com/style/client.css index 80ed47b035..a74db06434 100644 --- a/play.pokemonshowdown.com/style/client.css +++ b/play.pokemonshowdown.com/style/client.css @@ -1598,7 +1598,7 @@ a.ilink.yours { right: 0; width: auto; } -.tiny-layout .movecontrols, .tiny-layout .switchcontrols { +.tiny-layout .movecontrols, .tiny-layout .shiftcontrols, .tiny-layout .switchcontrols { max-width: 330px; margin: 0 auto; } @@ -1701,6 +1701,7 @@ a.ilink.yours { } .shiftselect button { color: #445588; + cursor: default; } .moveselect button { color: #884422; @@ -1929,7 +1930,7 @@ a.ilink.yours { color: #FF7766; border-color: #FF7766; } - .battle-controls .movecontrols, .battle-controls .switchcontrols { + .battle-controls .movecontrols, .battle-controls .shiftcontrols, .battle-controls .switchcontrols { max-width: 640px; } .movemenu { diff --git a/play.pokemonshowdown.com/style/client2.css b/play.pokemonshowdown.com/style/client2.css index 334aa64488..9f1654f6f1 100644 --- a/play.pokemonshowdown.com/style/client2.css +++ b/play.pokemonshowdown.com/style/client2.css @@ -1508,7 +1508,7 @@ a.ilink.yours { right: 0; width: auto; } -.tiny-layout .movecontrols, .tiny-layout .switchcontrols { +.tiny-layout .movecontrols, .tiny-layout .shiftcontrols, .tiny-layout .switchcontrols { max-width: 330px; margin: 0 auto; } From e4e95124f211a2dea3c09b9476371e17cb6de3d4 Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:37:35 -0700 Subject: [PATCH 756/770] News: Add support for minisprites (#2300) * News: Add support for minisprites * SANITIZE THE HTML. --- play.pokemonshowdown.com/js/client-mainmenu.js | 2 +- pokemonshowdown.com/news/manage.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/js/client-mainmenu.js b/play.pokemonshowdown.com/js/client-mainmenu.js index 08d9d05809..3106021cd6 100644 --- a/play.pokemonshowdown.com/js/client-mainmenu.js +++ b/play.pokemonshowdown.com/js/client-mainmenu.js @@ -132,7 +132,7 @@ options.noMinimize = options.noMinimize || false; this.$pmBox[options.append ? 'append' : 'prepend']('

    ' + (!options.noMinimize ? '' : '') + options.title + '

    ' + - options.html + + BattleLog.sanitizeHTML(options.html) + '
    '); }, diff --git a/pokemonshowdown.com/news/manage.php b/pokemonshowdown.com/news/manage.php index 883b875068..8e11e0b222 100644 --- a/pokemonshowdown.com/news/manage.php +++ b/pokemonshowdown.com/news/manage.php @@ -69,6 +69,8 @@ function saveNews() { $summary = str_replace("[/url]", '', $summary); $summary = str_replace("[b]", '', $summary); $summary = str_replace("[/b]", '', $summary); + $summary = preg_replace('/\[psicon (pokemon|item|type|category)="([^\]]+)"\]/', '', $summary); + $summary = preg_replace('/\[psicon (pokemon|item|type|category)=([^\]]+)\]/', '', $summary); $summary = '

    '.$summary.'

    '; $newsCache[$topic_id]['summary_html'] = $summary; @@ -88,6 +90,8 @@ function saveNews() { $details = str_replace("[/url]", '', $details); $details = str_replace("[b]", '', $details); $details = str_replace("[/b]", '', $details); + $details = preg_replace('/\[psicon (pokemon|item|type|category)="([^\]]+)"\]/', '', $details); + $details = preg_replace('/\[psicon (pokemon|item|type|category)=([^\]]+)\]/', '', $details); $details = '

    '.$details.'

    '; $newsCache[$topic_id]['details_html'] = $details; } else { From d43e960729eb980ec06b3e17f72bbe6d117ac186 Mon Sep 17 00:00:00 2001 From: "Alex \"Mathy" <4866817+MathyFurret@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:05:56 -0600 Subject: [PATCH 757/770] Fix Morpeko forme locking (#2303) --- play.pokemonshowdown.com/src/battle.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index 02c22f8a5f..89036a7772 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -2520,16 +2520,20 @@ export class Battle { case '-terastallize': { let poke = this.getPokemon(args[1])!; let type = Dex.types.get(args[2]).name; + let lockForme = false; poke.removeVolatile('typeadd' as ID); poke.teraType = type; poke.terastallized = type; poke.details += `, tera:${type}`; poke.searchid += `, tera:${type}`; if (poke.speciesForme.startsWith("Morpeko")) { + lockForme = true; + poke.speciesForme = poke.getSpeciesForme(); poke.details = poke.details.replace("Morpeko", poke.speciesForme); poke.searchid = `${poke.ident}|${poke.details}`; + delete poke.volatiles['formechange']; } - this.scene.animTransform(poke, true); + this.scene.animTransform(poke, true, lockForme); this.scene.resetStatbar(poke); this.log(args, kwArgs); break; From a77ed2a881d483831aa1857da266cc2d20ffbacd Mon Sep 17 00:00:00 2001 From: "Alex \"Mathy" <4866817+MathyFurret@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:08:49 -0600 Subject: [PATCH 758/770] Support blank target in -item message (#2302) * Support blank target in -item message * TS fix * TS fix again --- play.pokemonshowdown.com/src/battle.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index 89036a7772..6a298afcef 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -2231,6 +2231,20 @@ export class Battle { let item = Dex.items.get(args[2]); let effect = Dex.getEffect(kwArgs.from); let ofpoke = this.getPokemon(kwArgs.of); + if (!poke) { + if (effect.id === 'frisk') { + const possibleTargets = ofpoke!.side.foe.active.filter(p => p !== null); + if (possibleTargets.length === 1) { + poke = possibleTargets[0]!; + } else { + this.activateAbility(ofpoke!, "Frisk"); + this.log(args, kwArgs); + break; + } + } else { + throw new Error('No Pokemon in -item message'); + } + } poke.item = item.name; poke.itemEffect = ''; poke.removeVolatile('airballoon' as ID); From 3e855da7ae4f334e5b9e5f0852bc8327afd395f6 Mon Sep 17 00:00:00 2001 From: CarlosGuzman01 <120758068+CarlosGuzman01@users.noreply.github.com> Date: Fri, 29 Nov 2024 17:05:16 -0500 Subject: [PATCH 759/770] Update credits link for artist Seiryuuden (#2306) --- play.pokemonshowdown.com/js/storage.js | 2 +- play.pokemonshowdown.com/src/client-core.ts | 2 +- pokemonshowdown.com/credits.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/play.pokemonshowdown.com/js/storage.js b/play.pokemonshowdown.com/js/storage.js index 8ca36a79bf..4fa18fbefd 100644 --- a/play.pokemonshowdown.com/js/storage.js +++ b/play.pokemonshowdown.com/js/storage.js @@ -107,7 +107,7 @@ Storage.bg = { break; case 'charizards': hues = ["37.159090909090914,74.57627118644066%", "10.874999999999998,70.79646017699115%", "179.51612903225808,52.10084033613446%", "20.833333333333336,36.73469387755102%", "192.3076923076923,80.41237113402063%", "210,29.629629629629633%"]; - attrib = '"Charizards" background by Jessica Valencia'; + attrib = '"Charizards" background by Jessica Valencia'; break; case 'psday': hues = ["24.705882352941174,25.37313432835821%", "260.4651162790697,59.44700460829492%", "165.3191489361702,46.07843137254901%", "16.363636363636367,42.63565891472869%", "259.04761904761904,34.05405405405405%", "24.705882352941174,25.37313432835821%"]; diff --git a/play.pokemonshowdown.com/src/client-core.ts b/play.pokemonshowdown.com/src/client-core.ts index bee487d2cf..21e2c2ea67 100644 --- a/play.pokemonshowdown.com/src/client-core.ts +++ b/play.pokemonshowdown.com/src/client-core.ts @@ -303,7 +303,7 @@ const PSBackground = new class extends PSStreamModel { "210,29.629629629629633%", ]; attrib = { - url: 'https://seiryuuden.deviantart.com/art/The-Ultimate-Mega-Showdown-Charizards-414587079', + url: 'https://lit.link/en/seiryuuden', title: 'Charizards', artist: 'Jessica Valencia', }; diff --git a/pokemonshowdown.com/credits.php b/pokemonshowdown.com/credits.php index 3b882d3719..fc4d9dc78b 100644 --- a/pokemonshowdown.com/credits.php +++ b/pokemonshowdown.com/credits.php @@ -129,7 +129,7 @@
    • Daniel Kong – Art (Shaymin background)

    • -
    • Jessica Valencia [seiryuuden] – Art (Charizards background)

    • +
    • Jessica Valencia [seiryuuden] – Art (Charizards background)

    • Kyle Dove – Art (battle backdrops)

    • Vivian Zou [Vtas] – Art (Horizon background)

    • Samuel Teo [Yilx] – Art (Waterfall background)

    • From 72055f2d6e87a022436bd4773477d9052e74c70c Mon Sep 17 00:00:00 2001 From: CarlosGuzman01 <120758068+CarlosGuzman01@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:08:18 -0500 Subject: [PATCH 760/770] Update credits link for artist Yilx (#2307) --- play.pokemonshowdown.com/js/storage.js | 2 +- play.pokemonshowdown.com/src/client-core.ts | 2 +- pokemonshowdown.com/credits.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/play.pokemonshowdown.com/js/storage.js b/play.pokemonshowdown.com/js/storage.js index 4fa18fbefd..b54dd76efe 100644 --- a/play.pokemonshowdown.com/js/storage.js +++ b/play.pokemonshowdown.com/js/storage.js @@ -99,7 +99,7 @@ Storage.bg = { break; case 'waterfall': hues = ["119.31034482758622,37.66233766233767%", "184.36363636363635,23.012552301255226%", "108.92307692307692,37.14285714285714%", "70.34482758620689,20.567375886524818%", "98.39999999999998,36.76470588235296%", "140,38.18181818181818%"]; - attrib = '"Irie" background by Samuel Teo'; + attrib = '"Irie" background by Samuel Teo'; break; case 'shaymin': hues = ["39.000000000000064,21.7391304347826%", "170.00000000000003,2.380952380952378%", "157.5,11.88118811881188%", "174.78260869565216,12.041884816753928%", "185.00000000000003,12.76595744680851%", "20,5.660377358490567%"]; diff --git a/play.pokemonshowdown.com/src/client-core.ts b/play.pokemonshowdown.com/src/client-core.ts index 21e2c2ea67..ebb9cff35d 100644 --- a/play.pokemonshowdown.com/src/client-core.ts +++ b/play.pokemonshowdown.com/src/client-core.ts @@ -273,7 +273,7 @@ const PSBackground = new class extends PSStreamModel { "140,38.18181818181818%", ]; attrib = { - url: 'https://yilx.deviantart.com/art/Irie-372292729', + url: 'https://x.com/Yilxaevum', title: 'Irie', artist: 'Samuel Teo', }; diff --git a/pokemonshowdown.com/credits.php b/pokemonshowdown.com/credits.php index fc4d9dc78b..0ced58663e 100644 --- a/pokemonshowdown.com/credits.php +++ b/pokemonshowdown.com/credits.php @@ -132,7 +132,7 @@
    • Jessica Valencia [seiryuuden] – Art (Charizards background)

    • Kyle Dove – Art (battle backdrops)

    • Vivian Zou [Vtas] – Art (Horizon background)

    • -
    • Samuel Teo [Yilx] – Art (Waterfall background)

    • +
    • Samuel Teo [Yilx] – Art (Waterfall background)

    • [Quanyails] – Art (Ocean background)

    • X/Y and Sun/Moon Sprite Projects led by Ian Clail [Layell]– Sprites

    • Sun/Moon and Sword/Shield Sprite Projects led by [leparagon] – Sprites

    • From 565a057a5deb0cbea2c3eada0418b1cb24d6300c Mon Sep 17 00:00:00 2001 From: Marty Date: Sun, 1 Dec 2024 21:48:12 -0500 Subject: [PATCH 761/770] Update Pokemon icons sheet --- play.pokemonshowdown.com/src/battle-dex-data.ts | 1 + play.pokemonshowdown.com/src/battle-dex.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/src/battle-dex-data.ts b/play.pokemonshowdown.com/src/battle-dex-data.ts index 4761bc4997..4d31317de7 100644 --- a/play.pokemonshowdown.com/src/battle-dex-data.ts +++ b/play.pokemonshowdown.com/src/battle-dex-data.ts @@ -621,6 +621,7 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { scattervein: 1512 + 72, cresceidon: 1512 + 73, chuggalong: 1512 + 74, + shox: 1512 + 75, }; const BattlePokemonIconIndexesLeft: {[id: string]: number} = { diff --git a/play.pokemonshowdown.com/src/battle-dex.ts b/play.pokemonshowdown.com/src/battle-dex.ts index e45aacc0f7..1ddb5a25e5 100644 --- a/play.pokemonshowdown.com/src/battle-dex.ts +++ b/play.pokemonshowdown.com/src/battle-dex.ts @@ -732,7 +732,7 @@ const Dex = new class implements ModdedDex { let top = Math.floor(num / 12) * 30; let left = (num % 12) * 40; let fainted = ((pokemon as Pokemon | ServerPokemon)?.fainted ? `;opacity:.3;filter:grayscale(100%) brightness(.5)` : ``); - return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v16) no-repeat scroll -${left}px -${top}px${fainted}`; + return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v17) no-repeat scroll -${left}px -${top}px${fainted}`; } getTeambuilderSpriteData(pokemon: any, gen: number = 0): TeambuilderSpriteData { From f4baa241257350654aa441b1963e3b0761bbc51d Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 4 Dec 2024 04:52:12 +0000 Subject: [PATCH 762/770] Fix in Replays Apparently Caja CSS isn't loaded in Replays? Bypassed that dependency for . --- play.pokemonshowdown.com/src/battle-log.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-log.ts b/play.pokemonshowdown.com/src/battle-log.ts index c078c16a42..44edcd0e88 100644 --- a/play.pokemonshowdown.com/src/battle-log.ts +++ b/play.pokemonshowdown.com/src/battle-log.ts @@ -873,6 +873,8 @@ export class BattleLog { let dataUri = ''; let targetReplace = false; + // if Caja CSS isn't loaded, we still trust CSS + let unsanitizedStyle = ''; if (tagName === 'a') { if (getAttrib('target') === 'replace') { @@ -982,14 +984,13 @@ export class BattleLog { if (iconType) { const className = getAttrib('class'); - const style = getAttrib('style'); if (iconType === 'pokemon') { setAttrib('class', 'picon' + (className ? ' ' + className : '')); - setAttrib('style', Dex.getPokemonIcon(iconValue) + (style ? '; ' + style : '')); + unsanitizedStyle = Dex.getPokemonIcon(iconValue); } else if (iconType === 'item') { setAttrib('class', 'itemicon' + (className ? ' ' + className : '')); - setAttrib('style', Dex.getItemIcon(iconValue) + (style ? '; ' + style : '')); + unsanitizedStyle = Dex.getItemIcon(iconValue); } else if (iconType === 'type') { tagName = Dex.getTypeIcon(iconValue).slice(1, -3); } else if (iconType === 'category') { @@ -1002,6 +1003,10 @@ export class BattleLog { if (urlData.scheme_ === 'geo' || urlData.scheme_ === 'sms' || urlData.scheme_ === 'tel') return null; return urlData; }); + if (unsanitizedStyle) { + const style = getAttrib('style'); + setAttrib('style', unsanitizedStyle + (style ? '; ' + style : '')); + } if (dataUri && tagName === 'img') { setAttrib('src', dataUri); From ec3e54241c763ddc8b2c7fdf8e749e2230701691 Mon Sep 17 00:00:00 2001 From: bingingem <152201923+bingingem@users.noreply.github.com> Date: Fri, 20 Dec 2024 07:39:26 -0600 Subject: [PATCH 763/770] Staff FAQ: Fix missed Global Admin symbol updates (#2310) --- pokemonshowdown.com/pages/faq-ja.md | 4 ++-- pokemonshowdown.com/pages/rules-de.md | 2 +- pokemonshowdown.com/pages/rules-es.md | 2 +- pokemonshowdown.com/pages/rules-fr.md | 2 +- pokemonshowdown.com/pages/rules-hi.md | 2 +- pokemonshowdown.com/pages/rules-it.md | 2 +- pokemonshowdown.com/pages/rules-ja.md | 2 +- pokemonshowdown.com/pages/rules-nl.md | 2 +- pokemonshowdown.com/pages/rules-pl.md | 4 ++-- pokemonshowdown.com/pages/rules-pt.md | 2 +- pokemonshowdown.com/pages/rules-ru.md | 2 +- pokemonshowdown.com/pages/rules-tw.md | 2 +- pokemonshowdown.com/pages/rules-zh.md | 2 +- pokemonshowdown.com/pages/rules.md | 2 +- pokemonshowdown.com/pages/staff-de.md | 2 +- pokemonshowdown.com/pages/staff-es.md | 4 ++-- pokemonshowdown.com/pages/staff-ja.md | 4 ++-- pokemonshowdown.com/pages/staff.md | 2 +- 18 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pokemonshowdown.com/pages/faq-ja.md b/pokemonshowdown.com/pages/faq-ja.md index 49b9d66796..03bb5ac6fe 100644 --- a/pokemonshowdown.com/pages/faq-ja.md +++ b/pokemonshowdown.com/pages/faq-ja.md @@ -54,7 +54,7 @@ Smogonの[フォーラムガイドライン](http://www.smogon.com/forums/thread ### カスタムアバターを使用したい。 -カスタムアバターはグローバルドライバー(`%`、`@`、`&`)以上やPS!に貢献した人(プログラマーなど)やSmogonバッジを持っている人に与えられます。 カスタムアバターは手動で実装しなければならないため、要求されたユーザー全員に追加するのは現実的ではありません。例外もありますが、おそらくあなたは例外ではないでしょう。 +カスタムアバターはグローバルドライバー(`%`、`@`、`~`)以上やPS!に貢献した人(プログラマーなど)やSmogonバッジを持っている人に与えられます。 カスタムアバターは手動で実装しなければならないため、要求されたユーザー全員に追加するのは現実的ではありません。例外もありますが、おそらくあなたは例外ではないでしょう。 ### チャットルームを作るには? @@ -71,7 +71,7 @@ Smogonの[フォーラムガイドライン](http://www.smogon.com/forums/thread ### autoconfirmedとはなんですか? -レートが有効なバトルで1回以上勝利し、アカウントを登録してから1週間が経過するアカウントが自動承認されます(autoconfirmed)。承認されていないユーザーはグローバルスタッフ(いかなる場所でも名前の前に`%`、`@`、`&`がついています)以外にPMを送信することができません。また、チャットルームでは荒らしを防止するためにmodchatで承認済みのユーザーのみが発言できるようにすることができます。もしあなたが承認されていない場合はルームスタッフ(名前の前に`%`、`@`、`#`がついているユーザーです)にPMを送信し、modchatを無効にするように依頼することができます。 +レートが有効なバトルで1回以上勝利し、アカウントを登録してから1週間が経過するアカウントが自動承認されます(autoconfirmed)。承認されていないユーザーはグローバルスタッフ(いかなる場所でも名前の前に`%`、`@`、`~`がついています)以外にPMを送信することができません。また、チャットルームでは荒らしを防止するためにmodchatで承認済みのユーザーのみが発言できるようにすることができます。もしあなたが承認されていない場合はルームスタッフ(名前の前に`%`、`@`、`#`がついているユーザーです)にPMを送信し、modchatを無効にするように依頼することができます。 ### なぜチームが削除されたのですか? diff --git a/pokemonshowdown.com/pages/rules-de.md b/pokemonshowdown.com/pages/rules-de.md index 47b59a93f5..53f0bddde2 100755 --- a/pokemonshowdown.com/pages/rules-de.md +++ b/pokemonshowdown.com/pages/rules-de.md @@ -32,7 +32,7 @@ Du kannst deinen Nutzernamen jederzeit wählen oder ändern. Melde dich einfach ab und mit einem neuen Nutzernamen wieder an, wenn du ihn ändern möchtest. Doch bitte beachte: -1. **Namen dürfen keine Staff-Mitglieder** (Nutzer mit `%`, `@`, `#` oder `&` vor ihrem Namen) **oder berühmte Persönlichkeiten/Organisationen imitieren**, die PS benutzen oder mit Pokémon in Verbindung gebracht werden. +1. **Namen dürfen keine Staff-Mitglieder** (Nutzer mit `%`, `@`, `#` oder `~` vor ihrem Namen) **oder berühmte Persönlichkeiten/Organisationen imitieren**, die PS benutzen oder mit Pokémon in Verbindung gebracht werden. 2. **Namen dürfen keine Personen oder Gruppen beleidigen** (sich selbst zu beleidigen ist erlaubt, sofern es nicht zu ernst ist). diff --git a/pokemonshowdown.com/pages/rules-es.md b/pokemonshowdown.com/pages/rules-es.md index ae59c8e27d..8537c96aed 100755 --- a/pokemonshowdown.com/pages/rules-es.md +++ b/pokemonshowdown.com/pages/rules-es.md @@ -32,7 +32,7 @@ Puedes elegir un nombre de usuario y cambiarlo en cualquier momento (lo puedes cambiar desconectándote y conectándote de nuevo con un nuevo nombre). Ten en cuenta que: -1. **No hagas impersonating.** Los nombres de usuario no pueden ser demasiado parecidos al de un staff (usuarios con `%`, `@`, `#` o `&` al lado de su nombre) o a usuarios reconocidos que usen PS o estén asociados a Pokémon. +1. **No hagas impersonating.** Los nombres de usuario no pueden ser demasiado parecidos al de un staff (usuarios con `%`, `@`, `#` o `~` al lado de su nombre) o a usuarios reconocidos que usen PS o estén asociados a Pokémon. 2. **Los nombres no deben insultar a una persona o a un grupo.** Insultarte a ti mismo está permitido, siempre y cuando no sea nada demasiado serio. diff --git a/pokemonshowdown.com/pages/rules-fr.md b/pokemonshowdown.com/pages/rules-fr.md index 539d9e28d2..9e3b3df25b 100755 --- a/pokemonshowdown.com/pages/rules-fr.md +++ b/pokemonshowdown.com/pages/rules-fr.md @@ -32,7 +32,7 @@ Votre pseudo peut être choisi et modifié à tout moment (vous pouvez le changer en vous déconnectant et en vous reconnectant avec un autre pseudo). Gardez à l'esprit que : -1. **Les pseudos ne doivent pas imiter** ceux du staff (les utilisateurs avec les symboles `%`, `@`, `#`, ou `&` à côté de leur pseudo) ou de personnes/organisations connues qui utilisent PS ou sont associées à Pokémon. +1. **Les pseudos ne doivent pas imiter** ceux du staff (les utilisateurs avec les symboles `%`, `@`, `#`, ou `~` à côté de leur pseudo) ou de personnes/organisations connues qui utilisent PS ou sont associées à Pokémon. 2. **Les pseudos ne doivent pas être insultants**, que ce soit envers une personne ou un groupe (vous insulter vous même est accepté à la condition que ce ne soit pas trop sérieux). diff --git a/pokemonshowdown.com/pages/rules-hi.md b/pokemonshowdown.com/pages/rules-hi.md index f51e3b68c6..8c886afa24 100755 --- a/pokemonshowdown.com/pages/rules-hi.md +++ b/pokemonshowdown.com/pages/rules-hi.md @@ -32,7 +32,7 @@ आप अपना username कभी भी बदल सकते हैं. बस इतना ध्यान रखें: -1. **Username इनकी नकल नहीं कर सकते हैं**: staff (`%`, `@`, `#` या `&`) या कोई जाने माने व्यक्ति / संस्था जो की PS इस्तेमाल करते हैं या Pokémon संबंधी हैं. +1. **Username इनकी नकल नहीं कर सकते हैं**: staff (`%`, `@`, `#` या `~`) या कोई जाने माने व्यक्ति / संस्था जो की PS इस्तेमाल करते हैं या Pokémon संबंधी हैं. 2. **Usernames किसी के लिए अपमानजनक न हो** (खुद का अपमान कर सकते हैं, पर उसमें भी सीमित होनी चाहिए). diff --git a/pokemonshowdown.com/pages/rules-it.md b/pokemonshowdown.com/pages/rules-it.md index d13e1edc38..25dc1bf1fd 100755 --- a/pokemonshowdown.com/pages/rules-it.md +++ b/pokemonshowdown.com/pages/rules-it.md @@ -32,7 +32,7 @@ Il tuo username può essere scelto e cambiato in ogni momento (per farlo fai log out e rifai il log in scegliendone uno differente). Le regole a riguardo sono le seguenti: -1. **Gli username non devono impersonare** un membro dello staff (coloro che hanno `%`, `@`, `#`, o `&` a lato del proprio nome) o persone famose/organizzazioni che utilizzano PS o che sono associate con Pokémon. +1. **Gli username non devono impersonare** un membro dello staff (coloro che hanno `%`, `@`, `#`, o `~` a lato del proprio nome) o persone famose/organizzazioni che utilizzano PS o che sono associate con Pokémon. 2. **Gli username non devono insultare** o essere un'offesa ad un individuo o a un gruppo di individui (un insulto a te stesso è ok se non troppo pesante). diff --git a/pokemonshowdown.com/pages/rules-ja.md b/pokemonshowdown.com/pages/rules-ja.md index c49bae6206..1b4c935392 100755 --- a/pokemonshowdown.com/pages/rules-ja.md +++ b/pokemonshowdown.com/pages/rules-ja.md @@ -16,7 +16,7 @@ ## ユーザー名 ユーザー名はいつでも変更可能です(ログアウトして新しい名前でログインします)。以下のユーザー名は禁止されています: -1. スタッフ(名前の横に`%`、`@`、`#`、`&`のマークがあるユーザー)になりすますユーザー名 +1. スタッフ(名前の横に`%`、`@`、`#`、`~`のマークがあるユーザー)になりすますユーザー名 2. 個人や団体を侮辱するユーザー名 3. 下ネタ、過度に卑猥なユーザー名 4. 宣伝目的のユーザー名 diff --git a/pokemonshowdown.com/pages/rules-nl.md b/pokemonshowdown.com/pages/rules-nl.md index 316bec978f..0b08cdaa25 100755 --- a/pokemonshowdown.com/pages/rules-nl.md +++ b/pokemonshowdown.com/pages/rules-nl.md @@ -34,7 +34,7 @@ Je kunt op ieder moment een gebruikersnaam kiezen of hem wijzigen (wijzig hem door uit te loggen en in te loggen met een nieuwe gebruikersnaam). Let wel op: -1. **Gebruikersnamen mogen niet gebruikt worden om je vals voor te doen** als staf (iemand met een `%`, `@`, `#` of `&` voor zijn of haar naam) of bekende personen die PS gebruiken of in verbinding staan met Pokémon. +1. **Gebruikersnamen mogen niet gebruikt worden om je vals voor te doen** als staf (iemand met een `%`, `@`, `#` of `~` voor zijn of haar naam) of bekende personen die PS gebruiken of in verbinding staan met Pokémon. 2. **Gebruikersnamen mogen niet beledigend zijn** naar een groep of een individu (jezelf beledigen is toegestaan, zolang het niet al te serieus is). diff --git a/pokemonshowdown.com/pages/rules-pl.md b/pokemonshowdown.com/pages/rules-pl.md index 48b6aeea3a..4d7fde33d5 100755 --- a/pokemonshowdown.com/pages/rules-pl.md +++ b/pokemonshowdown.com/pages/rules-pl.md @@ -12,7 +12,7 @@ 4. **Nie oszukuj**. Nie wykorzystuj błędów, aby uzyskać nieuczciwą przewagę. Nie próbuj wykiwać systemu (przez celowe przegrywanie przeciwko sobie lub osobie którą znasz w walce rankingowej, oszukując przeciwnika do zastawienia gry, itd). Nie podawaj się za moderatora, jeżeli nim nie jesteś. -5. **Moderatorzy mają swobodę w karaniu zachowań**, które uznają za nieodpowiednie, niezależnie od tego czy jest ono na tej liście. Jeżeli nie zgadzasz się z ich orzeczeniem, odwołaj się do lidera (użytkownik z & na początku nazwy) lub do forum [Odwołania Dyscyplin](https://play.pokemonshowdown.com/view-help-request--appeal). +5. **Moderatorzy mają swobodę w karaniu zachowań**, które uznają za nieodpowiednie, niezależnie od tego czy jest ono na tej liście. Jeżeli nie zgadzasz się z ich orzeczeniem, odwołaj się do lidera (użytkownik z ~ na początku nazwy) lub do forum [Odwołania Dyscyplin](https://play.pokemonshowdown.com/view-help-request--appeal). (Uwaga: Poprawka do Konstytucji Stanów Zjednoczonych nie dotyczy PS, skoro PS nie jest rządową organizacją) @@ -32,7 +32,7 @@ Twoja nazwa użytkownika może być wybrana i zmieniona w dowolnym czasie (przez wylogowanie i zalogowanie z nową nazwą). Pamiętaj że: -1. **Nazwy użytkowników nie mogą podszywać się** pod znaną osobę (`%`, `@`, `#` lub `&` na lewo od nazwy) czy sławnej osoby/organizacji która używa PS albo jest powiązana z serią Pokémon. +1. **Nazwy użytkowników nie mogą podszywać się** pod znaną osobę (`%`, `@`, `#` lub `~` na lewo od nazwy) czy sławnej osoby/organizacji która używa PS albo jest powiązana z serią Pokémon. 2. **Nazwy użytkowników nie mogą obrażać** użytkownika albo grupy (można obrażać siebie, jeżeli to nie jest zbyt poważne). diff --git a/pokemonshowdown.com/pages/rules-pt.md b/pokemonshowdown.com/pages/rules-pt.md index ffe303c00c..56433eb1c0 100755 --- a/pokemonshowdown.com/pages/rules-pt.md +++ b/pokemonshowdown.com/pages/rules-pt.md @@ -32,7 +32,7 @@ Seu nome de usuário pode ser trocado a qualquer momento (mude-o dando log out e depois log in com um novo nome), mas tenha as seguintes regras em mente: -1. **Nomes não podem personificar** um membro do staff (usuários com `%`, `@`, `#` ou `&` frente ao nome) ou pessoas / organizações famosas que usam o PS ou são associadas a Pokémon. +1. **Nomes não podem personificar** um membro do staff (usuários com `%`, `@`, `#` ou `~` frente ao nome) ou pessoas / organizações famosas que usam o PS ou são associadas a Pokémon. 2. **Nomes não podem ofender** um indivíduo ou um grupo (insultar a si mesmo é aceitável, contanto que não seja algo muito sério). diff --git a/pokemonshowdown.com/pages/rules-ru.md b/pokemonshowdown.com/pages/rules-ru.md index 266c3744be..d6e1ec674e 100755 --- a/pokemonshowdown.com/pages/rules-ru.md +++ b/pokemonshowdown.com/pages/rules-ru.md @@ -32,7 +32,7 @@ Vashe imya pol'zovatelya mozhet byt' vybrano i izmeneno v lyuboye vremya (izmenite yego, vypolniv vkhod i voydya v sistemu s novym imenem pol'zovatelya). Imet' vvidu: -1. **Imena pol'zovateley ne mogut olitsetvoryat' priznannogo** pol'zovatelya (pol'zovatelya s %, @, #, Ili & ryadom s ikh imenem pol'zovatelya.) ili izvestnym chelovekom/organizatsiyey, kotoraya ispol'zuyet PS ili svyazana s Pokémon. +1. **Imena pol'zovateley ne mogut olitsetvoryat' priznannogo** pol'zovatelya (pol'zovatelya s %, @, #, Ili ~ ryadom s ikh imenem pol'zovatelya.) ili izvestnym chelovekom/organizatsiyey, kotoraya ispol'zuyet PS ili svyazana s Pokémon. 2. **Imena ne mogut oskorblyat' cheloveka ili gruppu. ** Oskorblyat' sebya mozhno, yesli eto ne slishkom ser'yezno. diff --git a/pokemonshowdown.com/pages/rules-tw.md b/pokemonshowdown.com/pages/rules-tw.md index ad5e01850f..7bbc430015 100755 --- a/pokemonshowdown.com/pages/rules-tw.md +++ b/pokemonshowdown.com/pages/rules-tw.md @@ -32,7 +32,7 @@ 用戶名可以隨時更改(注銷后重新起名)切記: -1. **用戶名不得模仿或冒充**以`%` `@` `#` `&`號標示的用戶。 +1. **用戶名不得模仿或冒充**以`%` `@` `#` `~`號標示的用戶。 2. **用戶名不得帶有對個人、團體的侮辱性字樣**。(侮辱自己可以,但不要太過了)。 diff --git a/pokemonshowdown.com/pages/rules-zh.md b/pokemonshowdown.com/pages/rules-zh.md index 04eee28624..34e6905743 100755 --- a/pokemonshowdown.com/pages/rules-zh.md +++ b/pokemonshowdown.com/pages/rules-zh.md @@ -32,7 +32,7 @@ 用户名可以随时更改(注销后重新起名)切记: -1. **用户名不得模仿或冒充**以`%` `@` `#` `&`号标示的用户。 +1. **用户名不得模仿或冒充**以`%` `@` `#` `~`号标示的用户。 2. **用户名不得带有对个人、团体的侮辱性字样**。(侮辱自己可以,但不要太过了)。 diff --git a/pokemonshowdown.com/pages/rules.md b/pokemonshowdown.com/pages/rules.md index 3a9a9e1b52..10acb272c8 100644 --- a/pokemonshowdown.com/pages/rules.md +++ b/pokemonshowdown.com/pages/rules.md @@ -36,7 +36,7 @@ Oh, wait, that wasn't the kind of rules we're talking about? Well, PS still rule Your username can be chosen and changed at any time (change it by logging out and logging in with a new username). Keep in mind: -1. **Names may not impersonate** staff (users with `%`, `@`, `#`, or `&` next to their name) or famous people/organizations that use PS or are associated with Pokémon. +1. **Names may not impersonate** staff (users with `%`, `@`, `#`, or `~` next to their name) or famous people/organizations that use PS or are associated with Pokémon. 2. **Names may not insult** an individual or group (insulting yourself is okay as long as it's not too serious). diff --git a/pokemonshowdown.com/pages/staff-de.md b/pokemonshowdown.com/pages/staff-de.md index e5712d7dbf..7f4e2467e7 100644 --- a/pokemonshowdown.com/pages/staff-de.md +++ b/pokemonshowdown.com/pages/staff-de.md @@ -20,7 +20,7 @@ Mitglieder des Raumstaffs besitzen Berechtigungen, welche sich ausschließlich a **Global Moderator (`@`)** können alles obrige und zusätzlich Nutzer vom Server verbannen, alle Berechtigungen eines Raum-Moderators ausführen und die IP-Adresse von Nutzern einsehen. -**Global Administrator (`&`)** können alles obrige und zusätzlich Nutzer auf jeden beliebigen Rang befördern, Unentschieden oder Siege herbeizwingen, serverweite Ankündigungen anzeigen lassen, Räume erstellen, IP-Bereiche sperren, Passwörter zurücksetzen und Nutzer permanent sperren und verbannen. +**Global Administrator (`~`)** können alles obrige und zusätzlich Nutzer auf jeden beliebigen Rang befördern, Unentschieden oder Siege herbeizwingen, serverweite Ankündigungen anzeigen lassen, Räume erstellen, IP-Bereiche sperren, Passwörter zurücksetzen und Nutzer permanent sperren und verbannen. ### Wie werde ich ein Staffmitglied? diff --git a/pokemonshowdown.com/pages/staff-es.md b/pokemonshowdown.com/pages/staff-es.md index 39153bd37c..a384233404 100644 --- a/pokemonshowdown.com/pages/staff-es.md +++ b/pokemonshowdown.com/pages/staff-es.md @@ -19,7 +19,7 @@ El room staff tiene poderes limitados a la sala en la que fueron ascendidos, mie **Global Moderators (`@`)** pueden hacer todo lo anterior, además de banear a usuarios del servidor, hacer todo lo que un Room Moderator puede hacer y comprobar la dirección IP de los usuarios. -**Global Administrators (`&`)** pueden: hacer todo lo anterior, además de ascender a usuarios a cualquier rango, forzar empates y victorias en batallas, hacer anuncios globales puntuales, crear salas, banear un rango de direcciones IPs, restablecer contraseñas y dar lock o ban permanentemente. +**Global Administrators (`~`)** pueden: hacer todo lo anterior, además de ascender a usuarios a cualquier rango, forzar empates y victorias en batallas, hacer anuncios globales puntuales, crear salas, banear un rango de direcciones IPs, restablecer contraseñas y dar lock o ban permanentemente. ### ¿Cómo me hago un miembro del Staff? @@ -50,4 +50,4 @@ Para llegar a ser Driver primero debes ser Voice. Ser Voice (`+`) te marca como - Contribuciones excepcionales en salas de PS! también pueden resultar en un ascenso global. -(Originalmente por [Birkal](https://www.smogon.com/forums/members/birkal.66676/) y [michael](https://www.smogon.com/forums/members/michael.94718/); actualizado por [Vacate](https://www.smogon.com/forums/members/vacate.189371/) y convertido a Markdown para la página de PS! por [Annika](https://www.smogon.com/forums/members/annika.434112/) y traducido al español por [Dorron](https://www.smogon.com/forums/members/dorron.475771/) y [Naziel](https://www.smogon.com/forums/members/naziel.407858/)) \ No newline at end of file +(Originalmente por [Birkal](https://www.smogon.com/forums/members/birkal.66676/) y [michael](https://www.smogon.com/forums/members/michael.94718/); actualizado por [Vacate](https://www.smogon.com/forums/members/vacate.189371/) y convertido a Markdown para la página de PS! por [Annika](https://www.smogon.com/forums/members/annika.434112/) y traducido al español por [Dorron](https://www.smogon.com/forums/members/dorron.475771/) y [Naziel](https://www.smogon.com/forums/members/naziel.407858/)) diff --git a/pokemonshowdown.com/pages/staff-ja.md b/pokemonshowdown.com/pages/staff-ja.md index 39df55f6fd..f1f603a386 100644 --- a/pokemonshowdown.com/pages/staff-ja.md +++ b/pokemonshowdown.com/pages/staff-ja.md @@ -2,7 +2,7 @@ ### 誰がスタッフ? -名前の左にシンボルマーク(`%`、`@`、`&`、`#`)がついているのがスタッフです。ユーザーリストの上部に表示されています。スタッフはPokémon Showdownのシニアユーザーであり、日々の円滑な運営に責任を負っています。スタッフのランクのリストは後述。 +名前の左にシンボルマーク(`%`、`@`、`~`、`#`)がついているのがスタッフです。ユーザーリストの上部に表示されています。スタッフはPokémon Showdownのシニアユーザーであり、日々の円滑な運営に責任を負っています。スタッフのランクのリストは後述。 ### ルームスタッフとグローバルスタッフの違いは? @@ -20,7 +20,7 @@ **Global Moderator (`@`)** 上記のほか、ユーザーをサーバからBAN、IPの確認が可能で、Room Moderatorの全権限も有しています。 -**Global Administrator (`&`)** 上記のほか、ユーザーを任意のランクに昇格、バトルを引き分けまたは一方の勝利にしたり、署名無しの告知文の作成、チャットルームの作成、IPによる範囲規制、パスワードのリセット、永久ロック・BANが可能。 +**Global Administrator (`~`)** 上記のほか、ユーザーを任意のランクに昇格、バトルを引き分けまたは一方の勝利にしたり、署名無しの告知文の作成、チャットルームの作成、IPによる範囲規制、パスワードのリセット、永久ロック・BANが可能。 ※Moderated chat… 設定したランク未満のユーザーが発言できなくすること diff --git a/pokemonshowdown.com/pages/staff.md b/pokemonshowdown.com/pages/staff.md index 595d3e6378..34e2211d9e 100644 --- a/pokemonshowdown.com/pages/staff.md +++ b/pokemonshowdown.com/pages/staff.md @@ -20,7 +20,7 @@ Room staff have permissions tied specifically to the room they were promoted in, **Global Moderators (`@`)** can do all of the above, as well as ban users from the server, do anything a Room Moderator can do, and check users' IP addresses. -**Global Administrators (`&`)** can: do all of the above, as well as promote users to any rank, force ties and wins in battle, make unsigned global declarations, create rooms, ban a range of IP addresses, reset passwords, and permanently lock / ban users. +**Global Administrators (`~`)** can: do all of the above, as well as promote users to any rank, force ties and wins in battle, make unsigned global declarations, create rooms, ban a range of IP addresses, reset passwords, and permanently lock / ban users. ### How do I become a staff member? From fac8296675772db863de3de45bbc63f57f7466be Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sat, 11 Jan 2025 12:40:32 -0700 Subject: [PATCH 764/770] Battle Animations: Add support for natures as effect tags --- play.pokemonshowdown.com/src/battle-animations.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index d1633213d2..4cb1ac5934 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -2859,6 +2859,8 @@ export class PokemonSprite extends Sprite { label = Dex.moves.get(id).name; } else if (Dex.abilities.get(id).exists) { label = Dex.abilities.get(id).name; + } else if (Dex.natures.get(id).exists) { + label = Dex.natures.get(id).name; } effect = [label, 'neutral']; } From dd3dc08a6d5b292fbaebc723748a7570d3bda69a Mon Sep 17 00:00:00 2001 From: Kris Johnson <11083252+KrisXV@users.noreply.github.com> Date: Sat, 11 Jan 2025 12:53:45 -0700 Subject: [PATCH 765/770] Battle Animations: Fix nature check because natures don't have a `get` function for some reason --- play.pokemonshowdown.com/src/battle-animations.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index 4cb1ac5934..bc04083545 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -2859,8 +2859,8 @@ export class PokemonSprite extends Sprite { label = Dex.moves.get(id).name; } else if (Dex.abilities.get(id).exists) { label = Dex.abilities.get(id).name; - } else if (Dex.natures.get(id).exists) { - label = Dex.natures.get(id).name; + } else if ((BattleNatures as any)[id.substr(0, 1).toUpperCase() + id.substr(1).toLowerCase()]) { + label = id.substr(0, 1).toUpperCase() + id.substr(1).toLowerCase(); } effect = [label, 'neutral']; } From 38d29ff6602e171c9b4c81b8ee040119124efea5 Mon Sep 17 00:00:00 2001 From: Marty Date: Tue, 11 Feb 2025 20:48:03 -0500 Subject: [PATCH 766/770] Update Pokemon icons sheet --- play.pokemonshowdown.com/src/battle-dex-data.ts | 2 ++ play.pokemonshowdown.com/src/battle-dex.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/play.pokemonshowdown.com/src/battle-dex-data.ts b/play.pokemonshowdown.com/src/battle-dex-data.ts index 4d31317de7..2bd7b4f02a 100644 --- a/play.pokemonshowdown.com/src/battle-dex-data.ts +++ b/play.pokemonshowdown.com/src/battle-dex-data.ts @@ -622,6 +622,8 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { cresceidon: 1512 + 73, chuggalong: 1512 + 74, shox: 1512 + 75, + chuggon: 1512 + 76, + draggalong: 1512 + 77, }; const BattlePokemonIconIndexesLeft: {[id: string]: number} = { diff --git a/play.pokemonshowdown.com/src/battle-dex.ts b/play.pokemonshowdown.com/src/battle-dex.ts index 1ddb5a25e5..148b2bd76f 100644 --- a/play.pokemonshowdown.com/src/battle-dex.ts +++ b/play.pokemonshowdown.com/src/battle-dex.ts @@ -732,7 +732,7 @@ const Dex = new class implements ModdedDex { let top = Math.floor(num / 12) * 30; let left = (num % 12) * 40; let fainted = ((pokemon as Pokemon | ServerPokemon)?.fainted ? `;opacity:.3;filter:grayscale(100%) brightness(.5)` : ``); - return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v17) no-repeat scroll -${left}px -${top}px${fainted}`; + return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-sheet.png?v18) no-repeat scroll -${left}px -${top}px${fainted}`; } getTeambuilderSpriteData(pokemon: any, gen: number = 0): TeambuilderSpriteData { From a40b4b37c80dc0896ea204fb74842c683e1ef45c Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Tue, 18 Feb 2025 19:19:28 -0800 Subject: [PATCH 767/770] Preact: Fix bugs with dragging tabs --- play.pokemonshowdown.com/src/panel-topbar.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/play.pokemonshowdown.com/src/panel-topbar.tsx b/play.pokemonshowdown.com/src/panel-topbar.tsx index 7a10fa7dfb..e473b3d32f 100644 --- a/play.pokemonshowdown.com/src/panel-topbar.tsx +++ b/play.pokemonshowdown.com/src/panel-topbar.tsx @@ -107,13 +107,17 @@ class PSHeader extends preact.Component<{style: {}}> { } if (fromRoomList !== toRoomList) { if (fromRoom === PS.leftRoom.id) { + if (PS.room === PS.mainmenu) PS.room = PS.mainmenu; PS.leftRoom = PS.mainmenu; } else if (PS.rightRoom && fromRoom === PS.rightRoom.id) { + if (PS.room === PS.rightRoom) PS.room = PS.rooms['rooms']!; PS.rightRoom = PS.rooms['rooms']!; } if (toRoomList === 'rightRoomList') { + if (PS.room === PS.rightRoom) PS.room = room; PS.rightRoom = room; } else if (toRoomList === 'leftRoomList') { + if (PS.room === PS.leftRoom) PS.room = room; PS.leftRoom = room; } } From 51657d5008c15ed6e0ee878dd54f84158dacf1e2 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 19 Feb 2025 00:47:33 -0800 Subject: [PATCH 768/770] Increase TypeScript strictness (Now with `noImplicitOverride`) --- package-lock.json | 11 ++++---- package.json | 2 +- .../src/battle-animations-moves.ts | 2 +- .../src/battle-animations.ts | 6 ++-- .../src/battle-dex-search.ts | 4 +-- play.pokemonshowdown.com/src/client-main.ts | 8 +++--- play.pokemonshowdown.com/src/panel-battle.tsx | 20 +++++++------ play.pokemonshowdown.com/src/panel-chat.tsx | 28 +++++++++---------- .../src/panel-example.tsx | 6 ++-- play.pokemonshowdown.com/src/panel-ladder.tsx | 6 ++-- .../src/panel-mainmenu.tsx | 14 ++++++---- play.pokemonshowdown.com/src/panel-page.tsx | 10 +++---- play.pokemonshowdown.com/src/panel-rooms.tsx | 8 +++--- .../src/panel-teambuilder-team.tsx | 6 ++-- .../src/panel-teambuilder.tsx | 4 +-- .../src/panel-teamdropdown.tsx | 4 +-- play.pokemonshowdown.com/src/panel-topbar.tsx | 10 +++---- play.pokemonshowdown.com/src/panels.tsx | 6 ++-- tsconfig.json | 7 ++++- 19 files changed, 87 insertions(+), 75 deletions(-) diff --git a/package-lock.json b/package-lock.json index 150f3cbc47..ad3eb5e3ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "preact": "^8.3.1", "source-map": "^0.7.3", "tslint": "^5.20.1", - "typescript": "^4.9.5" + "typescript": "^5.7.3" } }, "node_modules/@ampproject/remapping": { @@ -4931,16 +4931,17 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { diff --git a/package.json b/package.json index 05c95aaf2a..170c2107d5 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "preact": "^8.3.1", "source-map": "^0.7.3", "tslint": "^5.20.1", - "typescript": "^4.9.5" + "typescript": "^5.7.3" }, "private": true } diff --git a/play.pokemonshowdown.com/src/battle-animations-moves.ts b/play.pokemonshowdown.com/src/battle-animations-moves.ts index 6f02d17059..ce4fb7ccc1 100644 --- a/play.pokemonshowdown.com/src/battle-animations-moves.ts +++ b/play.pokemonshowdown.com/src/battle-animations-moves.ts @@ -9,7 +9,7 @@ * @license CC0-1.0 */ -import {AnimTable, BattleOtherAnims} from './battle-animations'; +import {type AnimTable, BattleOtherAnims} from './battle-animations'; export const BattleMoveAnims: AnimTable = { taunt: { diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index bc04083545..1189b77879 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -1924,7 +1924,7 @@ export class PokemonSprite extends Sprite { this.cryurl = this.sp.cryurl; this.isFrontSprite = isFrontSprite; } - destroy() { + override destroy() { if (this.$el) this.$el.remove(); this.$el = null!; if (this.$statbar) this.$statbar.remove(); @@ -1934,12 +1934,12 @@ export class PokemonSprite extends Sprite { this.scene = null!; } - delay(time: number) { + override delay(time: number) { this.$el.delay(time); if (this.$sub) this.$sub.delay(time); return this; } - anim(end: ScenePos, transition?: string) { + override anim(end: ScenePos, transition?: string) { end = { x: this.x, y: this.y, diff --git a/play.pokemonshowdown.com/src/battle-dex-search.ts b/play.pokemonshowdown.com/src/battle-dex-search.ts index ab5f21c32c..853fa7e190 100644 --- a/play.pokemonshowdown.com/src/battle-dex-search.ts +++ b/play.pokemonshowdown.com/src/battle-dex-search.ts @@ -890,7 +890,7 @@ abstract class BattleTypedSearch { } class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { - sortRow: SearchRow = ['sortpokemon', '']; + override sortRow: SearchRow = ['sortpokemon', '']; getTable() { return BattlePokedex; } @@ -1330,7 +1330,7 @@ class BattleItemSearch extends BattleTypedSearch<'item'> { } class BattleMoveSearch extends BattleTypedSearch<'move'> { - sortRow: SearchRow = ['sortmove', '']; + override sortRow: SearchRow = ['sortmove', '']; getTable() { return BattleMovedex; } diff --git a/play.pokemonshowdown.com/src/client-main.ts b/play.pokemonshowdown.com/src/client-main.ts index 8e33e27e23..5309378df2 100644 --- a/play.pokemonshowdown.com/src/client-main.ts +++ b/play.pokemonshowdown.com/src/client-main.ts @@ -562,8 +562,8 @@ class PSRoom extends PSStreamModel implements RoomOptions { class PlaceholderRoom extends PSRoom { queue = [] as Args[]; - readonly classType: 'placeholder' = 'placeholder'; - receiveLine(args: Args) { + override readonly classType: 'placeholder' = 'placeholder'; + override receiveLine(args: Args) { this.queue.push(args); } } @@ -778,7 +778,7 @@ const PS = new class extends PSModel { if (!alreadyUpdating) this.update(true); } } - update(layoutAlreadyUpdated?: boolean) { + override update(layoutAlreadyUpdated?: boolean) { if (!layoutAlreadyUpdated) this.updateLayout(true); super.update(); } @@ -1046,7 +1046,7 @@ const PS = new class extends PSModel { const roomid = `pm-${[userid, myUserid].sort().join('-')}` as RoomID; if (this.rooms[roomid]) return this.rooms[roomid] as ChatRoom; this.join(roomid); - return this.rooms[roomid] as ChatRoom; + return this.rooms[roomid]! as ChatRoom; } addRoom(options: RoomOptions, noFocus?: boolean) { // support hardcoded PM room-IDs diff --git a/play.pokemonshowdown.com/src/panel-battle.tsx b/play.pokemonshowdown.com/src/panel-battle.tsx index 6e6d40a1c8..e86ab9a3d8 100644 --- a/play.pokemonshowdown.com/src/panel-battle.tsx +++ b/play.pokemonshowdown.com/src/panel-battle.tsx @@ -5,6 +5,9 @@ * @license AGPLv3 */ +// import preact from "../js/lib/preact"; +// import {Battle} from "./battle"; + type BattleDesc = { id: RoomID, minElo?: number | string, @@ -52,7 +55,7 @@ class BattlesPanel extends PSRoomPanel { {battle.p1} vs. {battle.p2} ; } - render() { + override render() { const room = this.props.room; return
      @@ -99,7 +102,7 @@ class BattleRoom extends ChatRoom { /** * @return true to prevent line from being sent to server */ - handleMessage(line: string) { + override handleMessage(line: string) { if (!line.startsWith('/') || line.startsWith('//')) return false; const spaceIndex = line.indexOf(' '); const cmd = spaceIndex >= 0 ? line.slice(1, spaceIndex) : line.slice(1); @@ -161,10 +164,10 @@ class BattleRoom extends ChatRoom { } class BattleDiv extends preact.Component { - shouldComponentUpdate() { + override shouldComponentUpdate() { return false; } - render() { + override render() { return
      ; } } @@ -217,7 +220,7 @@ class BattlePanel extends PSRoomPanel { send = (text: string) => { this.props.room.send(text); }; - focus() { + override focus() { this.base!.querySelector('textarea')!.focus(); } focusIfNoSelection = () => { @@ -265,7 +268,7 @@ class BattlePanel extends PSRoomPanel { } this.props.room.update(null); }; - componentDidMount() { + override componentDidMount() { const $elem = $(this.base!); const battle = new Battle({ $frame: $elem.find('.battle'), @@ -276,7 +279,7 @@ class BattlePanel extends PSRoomPanel { super.componentDidMount(); battle.subscribe(() => this.forceUpdate()); } - receiveLine(args: Args) { + override receiveLine(args: Args) { const room = this.props.room; switch (args[0]) { case 'initdone': @@ -668,8 +671,9 @@ class BattlePanel extends PSRoomPanel {
      ; }} + return null; } - render() { + override render() { const room = this.props.room; return diff --git a/play.pokemonshowdown.com/src/panel-chat.tsx b/play.pokemonshowdown.com/src/panel-chat.tsx index 482885ce63..79a40b0f0f 100644 --- a/play.pokemonshowdown.com/src/panel-chat.tsx +++ b/play.pokemonshowdown.com/src/panel-chat.tsx @@ -10,10 +10,10 @@ type MiniEdit = import('./miniedit').MiniEdit; declare const formatText: any; class ChatRoom extends PSRoom { - readonly classType: 'chat' | 'battle' = 'chat'; + override readonly classType: 'chat' | 'battle' = 'chat'; users: {[userid: string]: string} = {}; userCount = 0; - readonly canConnect = true; + override readonly canConnect = true; // PM-only properties pmTarget: string | null = null; @@ -28,7 +28,7 @@ class ChatRoom extends PSRoom { this.updateTarget(true); this.connect(); } - connect() { + override connect() { if (!this.connected) { if (!this.pmTarget) PS.send(`|/join ${this.id}`); this.connected = true; @@ -56,7 +56,7 @@ class ChatRoom extends PSRoom { /** * @return true to prevent line from being sent to server */ - handleMessage(line: string) { + override handleMessage(line: string) { if (!line.startsWith('/') || line.startsWith('//')) return false; const spaceIndex = line.indexOf(' '); const cmd = spaceIndex >= 0 ? line.slice(1, spaceIndex) : line.slice(1); @@ -109,7 +109,7 @@ class ChatRoom extends PSRoom { } this.update(null); } - send(line: string, direct?: boolean) { + override send(line: string, direct?: boolean) { this.updateTarget(); if (!direct && !line) return; if (!direct && this.handleMessage(line)) return; @@ -147,7 +147,7 @@ class ChatRoom extends PSRoom { this.addUser(username); this.update(null); } - destroy() { + override destroy() { if (this.pmTarget) this.connected = false; super.destroy(); } @@ -365,7 +365,7 @@ class ChatPanel extends PSRoomPanel { send = (text: string) => { this.props.room.send(text); }; - focus() { + override focus() { // Called synchronously after a forceUpdate, so before the DOM has // been updated to make the panel visible. The order isn't // important for textboxes, which can be focused while inside a @@ -411,7 +411,7 @@ class ChatPanel extends PSRoomPanel { room.challengedFormat = null; room.update(null); }; - render() { + override render() { const room = this.props.room; const tinyLayout = room.width < 450; @@ -446,18 +446,18 @@ class ChatPanel extends PSRoomPanel { class ChatUserList extends preact.Component<{room: ChatRoom, left?: number, minimized?: boolean}> { subscription: PSSubscription | null = null; - state = { + override state = { expanded: false, }; toggleExpanded = () => { this.setState({expanded: !this.state.expanded}); }; - componentDidMount() { + override componentDidMount() { this.subscription = this.props.room.subscribe(msg => { if (!msg) this.forceUpdate(); }); } - componentWillUnmount() { + override componentWillUnmount() { if (this.subscription) this.subscription.unsubscribe(); } render() { @@ -501,7 +501,7 @@ class ChatLog extends preact.Component<{ }> { log: BattleLog | null = null; subscription: PSSubscription | null = null; - componentDidMount() { + override componentDidMount() { if (!this.props.noSubscription) { this.log = new BattleLog(this.base! as HTMLDivElement); } @@ -527,10 +527,10 @@ class ChatLog extends preact.Component<{ }); this.setControlsJSX(this.props.children); } - componentWillUnmount() { + override componentWillUnmount() { if (this.subscription) this.subscription.unsubscribe(); } - shouldComponentUpdate(props: typeof ChatLog.prototype.props) { + override shouldComponentUpdate(props: typeof ChatLog.prototype.props) { if (props.class !== this.props.class) { this.base!.className = props.class; } diff --git a/play.pokemonshowdown.com/src/panel-example.tsx b/play.pokemonshowdown.com/src/panel-example.tsx index c30c2f7f53..0b7b81b8e4 100644 --- a/play.pokemonshowdown.com/src/panel-example.tsx +++ b/play.pokemonshowdown.com/src/panel-example.tsx @@ -10,14 +10,14 @@ // Example room with panel class ExampleRoom extends PSRoom { - readonly classType: string = 'example'; + override readonly classType: string = 'example'; constructor(options: RoomOptions) { super(options); } } class ExamplePanel extends PSRoomPanel { - render() { + override render() { const room = this.props.room; return

      Loading...

      @@ -33,7 +33,7 @@ PS.roomTypes['example'] = { // Example panel with no room class ExampleViewPanel extends PSRoomPanel { - render() { + override render() { const room = this.props.room; return

      Loading...

      diff --git a/play.pokemonshowdown.com/src/panel-ladder.tsx b/play.pokemonshowdown.com/src/panel-ladder.tsx index 81458c2403..bd5550cecf 100644 --- a/play.pokemonshowdown.com/src/panel-ladder.tsx +++ b/play.pokemonshowdown.com/src/panel-ladder.tsx @@ -8,7 +8,7 @@ */ class LadderRoom extends PSRoom { - readonly classType: string = 'ladder'; + override readonly classType: string = 'ladder'; readonly format?: string = this.id.split('-')[1]; notice?: string; searchValue: string = ''; @@ -137,7 +137,7 @@ function LadderFormat(props: {room: LadderRoom}) { } class LadderPanel extends PSRoomPanel { - componentDidMount() { + override componentDidMount() { const {room} = this.props; // Request ladder data either on mount or after BattleFormats are loaded if (BattleFormats && room.format !== undefined) room.requestLadderData(); @@ -227,7 +227,7 @@ class LadderPanel extends PSRoomPanel { ; }; - render() { + override render() { const {room} = this.props; return
      diff --git a/play.pokemonshowdown.com/src/panel-mainmenu.tsx b/play.pokemonshowdown.com/src/panel-mainmenu.tsx index 66f7ff9823..782a22be5a 100644 --- a/play.pokemonshowdown.com/src/panel-mainmenu.tsx +++ b/play.pokemonshowdown.com/src/panel-mainmenu.tsx @@ -5,12 +5,14 @@ * @license AGPLv3 */ +// import type {BattlesRoom} from "./panel-battle"; + type RoomInfo = { title: string, desc?: string, userCount?: number, section?: string, spotlight?: string, subRooms?: string[], }; class MainMenuRoom extends PSRoom { - readonly classType: string = 'mainmenu'; + override readonly classType: string = 'mainmenu'; userdetailsCache: {[userid: string]: { userid: ID, avatar?: string | number, @@ -25,7 +27,7 @@ class MainMenuRoom extends PSRoom { chat?: RoomInfo[], sectionTitles?: string[], } = {}; - receiveLine(args: Args) { + override receiveLine(args: Args) { const [cmd] = args; switch (cmd) { case 'challstr': { @@ -285,7 +287,7 @@ class MainMenuRoom extends PSRoom { } class NewsPanel extends PSRoomPanel { - render() { + override render() { return
      ; @@ -293,7 +295,7 @@ class NewsPanel extends PSRoomPanel { } class MainMenuPanel extends PSRoomPanel { - focus() { + override focus() { (this.base!.querySelector('button.big') as HTMLButtonElement).focus(); } submit = (e: Event) => { @@ -356,7 +358,7 @@ class MainMenuPanel extends PSRoomPanel { ; } - render() { + override render() { const onlineButton = ' button' + (PS.isOffline ? ' disabled' : ''); return ; } - render() { + override render() { const room = this.props.room; let teams: (Team | null)[] = PS.teams.list.slice(); diff --git a/play.pokemonshowdown.com/src/panel-teamdropdown.tsx b/play.pokemonshowdown.com/src/panel-teamdropdown.tsx index 0794f16cab..e0a49362f2 100644 --- a/play.pokemonshowdown.com/src/panel-teamdropdown.tsx +++ b/play.pokemonshowdown.com/src/panel-teamdropdown.tsx @@ -626,7 +626,7 @@ class TeamDropdownPanel extends PSRoomPanel { this.chooseParentValue(target.value); }; - render() { + override render() { const room = this.props.room; if (!room.parentElem) { return @@ -762,7 +762,7 @@ class FormatDropdownPanel extends PSRoomPanel { this.chooseParentValue(target.value); }; - render() { + override render() { const room = this.props.room; if (!room.parentElem) { return diff --git a/play.pokemonshowdown.com/src/panel-topbar.tsx b/play.pokemonshowdown.com/src/panel-topbar.tsx index e473b3d32f..205bba9181 100644 --- a/play.pokemonshowdown.com/src/panel-topbar.tsx +++ b/play.pokemonshowdown.com/src/panel-topbar.tsx @@ -261,7 +261,7 @@ preact.render(, document.body, document.getElementById('ps-frame')!); */ class UserRoom extends PSRoom { - readonly classType = 'user'; + override readonly classType = 'user'; userid: ID; name: string; isSelf: boolean; @@ -276,7 +276,7 @@ class UserRoom extends PSRoom { } class UserPanel extends PSRoomPanel { - render() { + override render() { const room = this.props.room; const user = PS.mainmenu.userdetailsCache[room.userid] || {userid: room.userid, avatar: '[loading]'}; const name = room.name.slice(1); @@ -405,13 +405,13 @@ class VolumePanel extends PSRoomPanel { PS.prefs.set('mute', !!checkbox.checked); PS.update(); }; - componentDidMount() { + override componentDidMount() { super.componentDidMount(); this.subscriptions.push(PS.prefs.subscribe(() => { this.forceUpdate(); })); } - render() { + override render() { const room = this.props.room; return

      Volume

      @@ -459,7 +459,7 @@ class OptionsPanel extends PSRoomPanel { PS.prefs.set('theme', theme); this.forceUpdate(); }; - render() { + override render() { const room = this.props.room; return

      Graphics

      diff --git a/play.pokemonshowdown.com/src/panels.tsx b/play.pokemonshowdown.com/src/panels.tsx index 3bffff1b1e..94b86e0592 100644 --- a/play.pokemonshowdown.com/src/panels.tsx +++ b/play.pokemonshowdown.com/src/panels.tsx @@ -120,7 +120,7 @@ PS.router = new PSRouter(); class PSRoomPanel extends preact.Component<{room: T}> { subscriptions: PSSubscription[] = []; - componentDidMount() { + override componentDidMount() { if (PS.room === this.props.room) this.focus(); this.props.room.onParentEvent = (id: string, e?: Event) => { if (id === 'focus') this.focus(); @@ -133,12 +133,12 @@ class PSRoomPanel extends preact.Component<{room: T}> this.props.room.setDimensions(this.base.offsetWidth, this.base.offsetHeight); } } - componentDidUpdate() { + override componentDidUpdate() { if (this.base && ['popup', 'semimodal-popup'].includes(this.props.room.location)) { this.props.room.setDimensions(this.base.offsetWidth, this.base.offsetHeight); } } - componentWillUnmount() { + override componentWillUnmount() { this.props.room.onParentEvent = null; for (const subscription of this.subscriptions) { subscription.unsubscribe(); diff --git a/tsconfig.json b/tsconfig.json index 170eca7f59..ee2d01359d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,13 @@ "noEmit": true, "target": "esnext", "module": "None", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "verbatimModuleSyntax": true, + "forceConsistentCasingInFileNames": true, "jsx": "preserve", - "strict": true + "strict": true, + "noImplicitOverride": true }, "types": [], "include": [ From 3f23c5a7382faeb9cceafaedc83cce6af5e9adb0 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 19 Feb 2025 14:46:12 -0800 Subject: [PATCH 769/770] Refactor TypeScript files to modules Due to the specific way we implement everything, none of these files are actually modules. But thanks to `babel-plugin-remove-import-export`, there's no reason why the code can't be written as modules. I wouldn't say I like modules, but it's what's popular and it's what people are used to and it's what tooling is built around. --- .../src/battle-animations.ts | 8 +- .../src/battle-choices.ts | 25 ++-- .../src/battle-dex-data.ts | 74 ++++----- .../src/battle-dex-search.ts | 30 ++-- play.pokemonshowdown.com/src/battle-dex.ts | 128 ++++++++++++---- play.pokemonshowdown.com/src/battle-log.ts | 4 + .../src/battle-scene-stub.ts | 6 +- .../src/battle-searchresults.tsx | 6 +- play.pokemonshowdown.com/src/battle-sound.ts | 1 + .../src/battle-text-parser.ts | 12 +- .../src/battle-tooltips.ts | 141 +++++++----------- play.pokemonshowdown.com/src/battle.ts | 47 +++--- .../src/client-connection.ts | 8 +- play.pokemonshowdown.com/src/client-core.ts | 6 +- play.pokemonshowdown.com/src/client-main.ts | 18 ++- play.pokemonshowdown.com/src/globals.d.ts | 23 +-- play.pokemonshowdown.com/src/panel-battle.tsx | 19 ++- play.pokemonshowdown.com/src/panel-chat.tsx | 20 ++- .../src/panel-example.tsx | 3 + play.pokemonshowdown.com/src/panel-ladder.tsx | 9 +- .../src/panel-mainmenu.tsx | 21 ++- play.pokemonshowdown.com/src/panel-page.tsx | 5 + play.pokemonshowdown.com/src/panel-rooms.tsx | 7 +- .../src/panel-teambuilder-team.tsx | 10 +- .../src/panel-teambuilder.tsx | 5 + .../src/panel-teamdropdown.tsx | 47 +++--- play.pokemonshowdown.com/src/panel-topbar.tsx | 13 +- play.pokemonshowdown.com/src/panels.tsx | 19 ++- tslint.json | 1 + 29 files changed, 448 insertions(+), 268 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index 1189b77879..1b18f73cdc 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -16,6 +16,10 @@ import type {BattleSceneStub} from './battle-scene-stub'; import {BattleMoveAnims} from './battle-animations-moves'; import {BattleLog} from './battle-log'; import {BattleBGM, BattleSound} from './battle-sound'; +import {Dex, toID, type ID, type SpriteData} from './battle-dex'; +import {BattleNatures} from './battle-dex-data'; +import {BattleTooltips} from './battle-tooltips'; +import {BattleTextParser, type Args, type KWArgs} from './battle-text-parser'; /* @@ -1399,7 +1403,7 @@ export class BattleScene implements BattleSceneStub { ).join(' '); this.resultAnim(pokemon, result, 'neutral'); } - resultAnim(pokemon: Pokemon, result: string, type: 'bad' | 'good' | 'neutral' | StatusName) { + resultAnim(pokemon: Pokemon, result: string, type: 'bad' | 'good' | 'neutral' | Dex.StatusName) { if (!this.animating) return; let $effect = $('
      ' + result + '
      '); this.$fx.append($effect); @@ -2827,7 +2831,7 @@ export class PokemonSprite extends Sprite { } for (const stat in pokemon.boosts) { if (pokemon.boosts[stat]) { - status += '' + pokemon.getBoost(stat as BoostStatName) + ' '; + status += '' + pokemon.getBoost(stat as Dex.BoostStatName) + ' '; } } diff --git a/play.pokemonshowdown.com/src/battle-choices.ts b/play.pokemonshowdown.com/src/battle-choices.ts index e44fd75a80..778c58c983 100644 --- a/play.pokemonshowdown.com/src/battle-choices.ts +++ b/play.pokemonshowdown.com/src/battle-choices.ts @@ -12,30 +12,33 @@ * @license MIT */ -interface BattleRequestSideInfo { +import type {Battle, ServerPokemon} from "./battle"; +import {Dex, toID, type ID} from "./battle-dex"; + +export interface BattleRequestSideInfo { name: string; id: 'p1' | 'p2' | 'p3' | 'p4'; pokemon: ServerPokemon[]; } -interface BattleRequestActivePokemon { +export interface BattleRequestActivePokemon { moves: { name: string, id: ID, pp: number, maxpp: number, - target: MoveTarget, + target: Dex.MoveTarget, disabled?: boolean, }[]; maxMoves?: { name: string, id: ID, - target: MoveTarget, + target: Dex.MoveTarget, disabled?: boolean, }[]; zMoves?: ({ name: string, id: ID, - target: MoveTarget, + target: Dex.MoveTarget, } | null)[]; /** also true if the pokemon can Gigantamax */ canDynamax?: boolean; @@ -49,34 +52,34 @@ interface BattleRequestActivePokemon { maybeTrapped?: boolean; } -interface BattleMoveRequest { +export interface BattleMoveRequest { requestType: 'move'; rqid: number; side: BattleRequestSideInfo; active: (BattleRequestActivePokemon | null)[]; noCancel?: boolean; } -interface BattleSwitchRequest { +export interface BattleSwitchRequest { requestType: 'switch'; rqid: number; side: BattleRequestSideInfo; forceSwitch: boolean[]; noCancel?: boolean; } -interface BattleTeamRequest { +export interface BattleTeamRequest { requestType: 'team'; rqid: number; side: BattleRequestSideInfo; maxTeamSize?: number; noCancel?: boolean; } -interface BattleWaitRequest { +export interface BattleWaitRequest { requestType: 'wait'; rqid: number; side: undefined; noCancel?: boolean; } -type BattleRequest = BattleMoveRequest | BattleSwitchRequest | BattleTeamRequest | BattleWaitRequest; +export type BattleRequest = BattleMoveRequest | BattleSwitchRequest | BattleTeamRequest | BattleWaitRequest; interface BattleMoveChoice { choiceType: 'move'; @@ -107,7 +110,7 @@ type BattleChoice = BattleMoveChoice | BattleShiftChoice | BattleSwitchChoice; * * Doesn't support going backwards; just use `new BattleChoiceBuilder`. */ -class BattleChoiceBuilder { +export class BattleChoiceBuilder { request: BattleRequest; /** Completed choices in string form */ choices: string[] = []; diff --git a/play.pokemonshowdown.com/src/battle-dex-data.ts b/play.pokemonshowdown.com/src/battle-dex-data.ts index 2bd7b4f02a..fd303cec6f 100644 --- a/play.pokemonshowdown.com/src/battle-dex-data.ts +++ b/play.pokemonshowdown.com/src/battle-dex-data.ts @@ -14,17 +14,19 @@ * @license MIT */ +import {Dex, toID} from "./battle-dex"; + /** * String that contains only lowercase alphanumeric characters. */ -type ID = string & {__isID: true}; +export type ID = string & {__isID: true}; -interface Nature { +export interface Nature { plus?: StatNameExceptHP; minus?: StatNameExceptHP; } -const BattleNatures: {[k in NatureName]: Nature} = { +export const BattleNatures: {[k in NatureName]: Nature} = { Adamant: { plus: 'atk', minus: 'spa', @@ -111,7 +113,7 @@ const BattleNatures: {[k in NatureName]: Nature} = { minus: 'atk', }, }; -const BattleStatIDs: {[k: string]: StatName | undefined} = { +export const BattleStatIDs: {[k: string]: StatName | undefined} = { HP: 'hp', hp: 'hp', Atk: 'atk', @@ -133,7 +135,7 @@ const BattleStatIDs: {[k: string]: StatName | undefined} = { spe: 'spe', }; /** Stat short names */ -const BattleStatNames = { +export const BattleStatNames = { hp: 'HP', atk: 'Atk', def: 'Def', @@ -142,11 +144,11 @@ const BattleStatNames = { spe: 'Spe', } as const; -const BattleBaseSpeciesChart = [ +export const BattleBaseSpeciesChart = [ "unown", "burmy", "shellos", "gastrodon", "deerling", "sawsbuck", "vivillon", "flabebe", "floette", "florges", "furfrou", "minior", "alcremie", "tatsugiri", "pokestarufo", "pokestarbrycenman", "pokestarmt", "pokestarmt2", "pokestartransport", "pokestargiant", "pokestarhumanoid", "pokestarmonster", "pokestarf00", "pokestarf002", "pokestarspirit", "pokestarblackdoor", "pokestarwhitedoor", "pokestarblackbelt", ] as ID[]; -const BattlePokemonIconIndexes: {[id: string]: number} = { +export const BattlePokemonIconIndexes: {[id: string]: number} = { // alt forms egg: 1032 + 1, pikachubelle: 1032 + 2, @@ -626,7 +628,7 @@ const BattlePokemonIconIndexes: {[id: string]: number} = { draggalong: 1512 + 77, }; -const BattlePokemonIconIndexesLeft: {[id: string]: number} = { +export const BattlePokemonIconIndexesLeft: {[id: string]: number} = { pikachubelle: 1404 + 0, pikachupopstar: 1404 + 1, clefairy: 1404 + 2, @@ -736,7 +738,7 @@ const BattlePokemonIconIndexesLeft: {[id: string]: number} = { blacephalon: 1404 + 105, }; -const BattleAvatarNumbers: {[k: string]: string} = { +export const BattleAvatarNumbers: {[k: string]: string} = { 1: 'lucas', 2: 'dawn', 3: 'youngster-gen4dp', @@ -1051,18 +1053,18 @@ const BattleAvatarNumbers: {[k: string]: string} = { 1010: '#1010', }; -type StatName = 'hp' | 'atk' | 'def' | 'spa' | 'spd' | 'spe'; -type NatureName = 'Adamant' | 'Bashful' | 'Bold' | 'Brave' | 'Calm' | 'Careful' | 'Docile' | 'Gentle' | +export type StatName = 'hp' | 'atk' | 'def' | 'spa' | 'spd' | 'spe'; +export type NatureName = 'Adamant' | 'Bashful' | 'Bold' | 'Brave' | 'Calm' | 'Careful' | 'Docile' | 'Gentle' | 'Hardy' | 'Hasty' | 'Impish' | 'Jolly' | 'Lax' | 'Lonely' | 'Mild' | 'Modest' | 'Naive' | 'Naughty' | 'Quiet' | 'Quirky' | 'Rash' | 'Relaxed' | 'Sassy' | 'Serious' | 'Timid'; -type StatNameExceptHP = 'atk' | 'def' | 'spa' | 'spd' | 'spe'; -type TypeName = 'Normal' | 'Fighting' | 'Flying' | 'Poison' | 'Ground' | 'Rock' | 'Bug' | 'Ghost' | 'Steel' | +export type StatNameExceptHP = 'atk' | 'def' | 'spa' | 'spd' | 'spe'; +export type TypeName = 'Normal' | 'Fighting' | 'Flying' | 'Poison' | 'Ground' | 'Rock' | 'Bug' | 'Ghost' | 'Steel' | 'Fire' | 'Water' | 'Grass' | 'Electric' | 'Psychic' | 'Ice' | 'Dragon' | 'Dark' | 'Fairy' | 'Stellar' | '???'; -type StatusName = 'par' | 'psn' | 'frz' | 'slp' | 'brn'; -type BoostStatName = 'atk' | 'def' | 'spa' | 'spd' | 'spe' | 'evasion' | 'accuracy' | 'spc'; -type GenderName = 'M' | 'F' | 'N'; +export type StatusName = 'par' | 'psn' | 'frz' | 'slp' | 'brn'; +export type BoostStatName = 'atk' | 'def' | 'spa' | 'spd' | 'spe' | 'evasion' | 'accuracy' | 'spc'; +export type GenderName = 'M' | 'F' | 'N'; -interface Effect { +export interface Effect { readonly id: ID; readonly name: string; readonly gen: number; @@ -1074,7 +1076,7 @@ interface Effect { readonly exists: boolean; } -class PureEffect implements Effect { +export class PureEffect implements Effect { readonly effectType = 'PureEffect'; readonly id: ID; readonly name: string; @@ -1088,7 +1090,7 @@ class PureEffect implements Effect { } } -class Item implements Effect { +export class Item implements Effect { // effect readonly effectType = 'Item'; readonly id: ID; @@ -1156,7 +1158,7 @@ class Item implements Effect { } } -interface MoveFlags { +export interface MoveFlags { /** The move has an animation when used on an ally. */ allyanim?: 1 | 0; /** Power is multiplied by 1.5 when used by a Pokemon with the Strong Jaw Ability. */ @@ -1207,12 +1209,12 @@ interface MoveFlags { wind?: 1 | 0; } -type MoveTarget = 'normal' | 'any' | 'adjacentAlly' | 'adjacentFoe' | 'adjacentAllyOrSelf' | // single-target +export type MoveTarget = 'normal' | 'any' | 'adjacentAlly' | 'adjacentFoe' | 'adjacentAllyOrSelf' | // single-target 'self' | 'randomNormal' | // single-target, automatic 'allAdjacent' | 'allAdjacentFoes' | // spread 'allySide' | 'foeSide' | 'all'; // side and field -class Move implements Effect { +export class Move implements Effect { // effect readonly effectType = 'Move'; readonly id: ID; @@ -1383,7 +1385,7 @@ class Move implements Effect { } } -interface AbilityFlags { +export interface AbilityFlags { /** Can be suppressed by Mold Breaker and related effects */ breakable?: 1; /** Ability can't be suppressed by e.g. Gastro Acid or Neutralizing Gas */ @@ -1402,7 +1404,7 @@ interface AbilityFlags { notransform?: 1; } -class Ability implements Effect { +export class Ability implements Effect { // effect readonly effectType = 'Ability'; readonly id: ID; @@ -1449,7 +1451,7 @@ class Ability implements Effect { } } -class Species implements Effect { +export class Species implements Effect { // effect readonly effectType = 'Species'; readonly id: ID; @@ -1592,19 +1594,21 @@ class Species implements Effect { } } -interface Type extends Effect { +export interface Type extends Effect { damageTaken?: AnyObject; - HPivs?: Partial; - HPdvs?: Partial; + HPivs?: Partial; + HPdvs?: Partial; } +declare const require: any; +declare const global: any; if (typeof require === 'function') { // in Node - (global as any).BattleBaseSpeciesChart = BattleBaseSpeciesChart; - (global as any).BattleNatures = BattleNatures; - (global as any).PureEffect = PureEffect; - (global as any).Species = Species; - (global as any).Ability = Ability; - (global as any).Item = Item; - (global as any).Move = Move; + global.BattleBaseSpeciesChart = BattleBaseSpeciesChart; + global.BattleNatures = BattleNatures; + global.PureEffect = PureEffect; + global.Species = Species; + global.Ability = Ability; + global.Item = Item; + global.Move = Move; } diff --git a/play.pokemonshowdown.com/src/battle-dex-search.ts b/play.pokemonshowdown.com/src/battle-dex-search.ts index 853fa7e190..71d58df8da 100644 --- a/play.pokemonshowdown.com/src/battle-dex-search.ts +++ b/play.pokemonshowdown.com/src/battle-dex-search.ts @@ -11,11 +11,13 @@ * @license MIT */ +import {Dex, ModdedDex, toID, type ID} from "./battle-dex"; + type SearchType = ( 'pokemon' | 'type' | 'tier' | 'move' | 'item' | 'ability' | 'egggroup' | 'category' | 'article' ); -type SearchRow = ( +export type SearchRow = ( [SearchType, ID, number?, number?] | ['sortpokemon' | 'sortmove', ''] | ['header' | 'html', string] ); @@ -29,7 +31,7 @@ declare const BattleTeambuilderTable: any; /** * Backend for search UIs. */ -class DexSearch { +export class DexSearch { query = ''; /** @@ -84,7 +86,7 @@ class DexSearch { this.setType(searchType, formatid, species); } - getTypedSearch(searchType: SearchType | '', format = '' as ID, speciesOrSet: ID | PokemonSet = '' as ID) { + getTypedSearch(searchType: SearchType | '', format = '' as ID, speciesOrSet: ID | Dex.PokemonSet = '' as ID) { if (!searchType) return null; switch (searchType) { case 'pokemon': return new BattlePokemonSearch('pokemon', format, speciesOrSet); @@ -111,7 +113,7 @@ class DexSearch { return true; } - setType(searchType: SearchType | '', format = '' as ID, speciesOrSet: ID | PokemonSet = '' as ID) { + setType(searchType: SearchType | '', format = '' as ID, speciesOrSet: ID | Dex.PokemonSet = '' as ID) { // invalidate caches this.results = null; @@ -198,7 +200,7 @@ class DexSearch { return this.typedSearch?.illegalReasons?.[id] || null; } - getTier(species: Species) { + getTier(species: Dex.Species) { return this.typedSearch?.getTier(species) || ''; } @@ -457,7 +459,7 @@ class DexSearch { if (searchType === 'pokemon') { switch (fType) { case 'type': - let type = fId.charAt(0).toUpperCase() + fId.slice(1) as TypeName; + let type = fId.charAt(0).toUpperCase() + fId.slice(1) as Dex.TypeName; buf.push(['header', `${type}-type Pokémon`]); for (let id in BattlePokedex) { if (!BattlePokedex[id].types) continue; @@ -547,7 +549,7 @@ abstract class BattleTypedSearch { * `set` is a pseudo-base filter; it has minor effects on move sorting. * (Abilities/items can affect what moves are sorted as usable.) */ - set: PokemonSet | null = null; + set: Dex.PokemonSet | null = null; protected formatType: 'doubles' | 'bdsp' | 'bdspdoubles' | 'bw1' | 'letsgo' | 'metronome' | 'natdex' | 'nfe' | 'ssdlc1' | 'ssdlc1doubles' | 'predlc' | 'predlcdoubles' | 'predlcnatdex' | 'svdlc1' | 'svdlc1doubles' | @@ -568,7 +570,7 @@ abstract class BattleTypedSearch { protected readonly sortRow: SearchRow | null = null; - constructor(searchType: T, format = '' as ID, speciesOrSet: ID | PokemonSet = '' as ID) { + constructor(searchType: T, format = '' as ID, speciesOrSet: ID | Dex.PokemonSet = '' as ID) { this.searchType = searchType; this.baseResults = null; @@ -666,7 +668,7 @@ abstract class BattleTypedSearch { if (typeof speciesOrSet === 'string') { if (speciesOrSet) this.species = speciesOrSet; } else { - this.set = speciesOrSet as PokemonSet; + this.set = speciesOrSet as Dex.PokemonSet; this.species = toID(this.set.species); } if (!searchType || !this.set) return; @@ -830,7 +832,7 @@ abstract class BattleTypedSearch { } return false; } - getTier(pokemon: Species) { + getTier(pokemon: Dex.Species) { if (this.formatType === 'metronome') { return pokemon.num >= 0 ? String(pokemon.num) : pokemon.tier; } @@ -1149,8 +1151,8 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> { const sortOrder = reverseSort ? -1 : 1; if (['hp', 'atk', 'def', 'spa', 'spd', 'spe'].includes(sortCol)) { return results.sort(([rowType1, id1], [rowType2, id2]) => { - const stat1 = this.dex.species.get(id1).baseStats[sortCol as StatName]; - const stat2 = this.dex.species.get(id2).baseStats[sortCol as StatName]; + const stat1 = this.dex.species.get(id1).baseStats[sortCol as Dex.StatName]; + const stat2 = this.dex.species.get(id2).baseStats[sortCol as Dex.StatName]; return (stat2 - stat1) * sortOrder; }); } else if (sortCol === 'bst') { @@ -1349,7 +1351,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { } return results; } - private moveIsNotUseless(id: ID, species: Species, moves: string[], set: PokemonSet | null) { + private moveIsNotUseless(id: ID, species: Dex.Species, moves: string[], set: Dex.PokemonSet | null) { const dex = this.dex; let abilityid: ID = set ? toID(set.ability) : '' as ID; @@ -1743,7 +1745,7 @@ class BattleMoveSearch extends BattleTypedSearch<'move'> { if (pokemon.battleOnly && typeof pokemon.battleOnly === 'string') { species = dex.species.get(pokemon.battleOnly); } - const excludedForme = (s: Species) => [ + const excludedForme = (s: Dex.Species) => [ 'Alola', 'Alola-Totem', 'Galar', 'Galar-Zen', 'Hisui', 'Paldea', 'Paldea-Combat', 'Paldea-Blaze', 'Paldea-Aqua', ].includes(s.forme); if (baseSpecies.otherFormes && !['Wormadam', 'Urshifu'].includes(baseSpecies.baseSpecies)) { diff --git a/play.pokemonshowdown.com/src/battle-dex.ts b/play.pokemonshowdown.com/src/battle-dex.ts index 148b2bd76f..61b378df1d 100644 --- a/play.pokemonshowdown.com/src/battle-dex.ts +++ b/play.pokemonshowdown.com/src/battle-dex.ts @@ -18,12 +18,83 @@ * @license MIT */ -declare var require: any; -declare var global: any; +import {Pokemon, type ServerPokemon} from "./battle"; +import { + BattleAvatarNumbers, BattleBaseSpeciesChart, BattlePokemonIconIndexes, BattlePokemonIconIndexesLeft, BattleStatNames, + Ability, Item, Move, Species, PureEffect, type ID, type Type, +} from "./battle-dex-data"; +// tslint:disable-next-line +import * as DexData from "./battle-dex-data"; + +export declare namespace Dex { + /* tslint:disable:no-shadowed-variable */ + export type Ability = DexData.Ability; + export type Item = DexData.Item; + export type Move = DexData.Move; + export type Species = DexData.Species; + export type Type = DexData.Type; + export type Nature = DexData.Nature; + export type PureEffect = DexData.PureEffect; + export type Effect = DexData.Effect; + export type ID = DexData.ID; + /* tslint:enable:no-shadowed-variable */ + export type StatName = DexData.StatName; + export type StatNameExceptHP = DexData.StatNameExceptHP; + export type BoostStatName = DexData.BoostStatName; + export type TypeName = DexData.TypeName; + export type StatusName = DexData.StatusName; + export type GenderName = DexData.GenderName; + export type NatureName = DexData.NatureName; + export type MoveTarget = DexData.MoveTarget; + export type StatsTable = {hp: number, atk: number, def: number, spa: number, spd: number, spe: number}; + /** + * Dex.PokemonSet can be sparse, in which case that entry should be + * inferred from the rest of the set, according to sensible + * defaults. + */ + export interface PokemonSet { + /** Defaults to species name (not including forme), like in games */ + name?: string; + species: string; + /** Defaults to no item */ + item?: string; + /** Defaults to no ability (error in Gen 3+) */ + ability?: string; + moves: string[]; + /** Defaults to no nature (error in Gen 3+) */ + nature?: NatureName; + /** Defaults to random legal gender, NOT subject to gender ratios */ + gender?: string; + /** Defaults to flat 252's (200's/0's in Let's Go) (error in gen 3+) */ + evs?: Partial; + /** Defaults to whatever makes sense - flat 31's unless you have Gyro Ball etc */ + ivs?: Dex.StatsTable; + /** Defaults as you'd expect (100 normally, 50 in VGC-likes, 5 in LC) */ + level?: number; + /** Defaults to no (error if shiny event) */ + shiny?: boolean; + /** Defaults to 255 unless you have Frustration, in which case 0 */ + happiness?: number; + /** Defaults to event required ball, otherwise Poké Ball */ + pokeball?: string; + /** Defaults to the type of your Hidden Power in Moves, otherwise Dark */ + hpType?: string; + /** Defaults to 10 */ + dynamaxLevel?: number; + /** Defaults to no (can only be yes for certain Pokemon) */ + gigantamax?: boolean; + /** Defaults to the primary type */ + teraType?: string; + } +} +export type {ID}; + +declare const require: any; +declare const global: any; if (typeof window === 'undefined') { // Node - (global as any).window = global; + global.window = global; } else { // browser (possibly NW.js!) window.exports = window; @@ -32,7 +103,7 @@ if (typeof window === 'undefined') { // @ts-ignore window.nodewebkit = !!(typeof process !== 'undefined' && process.versions && process.versions['node-webkit']); -function toID(text: any) { +export function toID(text: any) { if (text?.id) { text = text.id; } else if (text?.userid) { @@ -42,12 +113,12 @@ function toID(text: any) { return ('' + text).toLowerCase().replace(/[^a-z0-9]+/g, '') as ID; } -function toUserid(text: any) { +export function toUserid(text: any) { return toID(text); } type Comparable = number | string | boolean | Comparable[] | {reverse: Comparable}; -const PSUtils = new class { +export const PSUtils = new class { /** * Like string.split(delimiter), but only recognizes the first `limit` * delimiters (default 1). @@ -129,11 +200,11 @@ const PSUtils = new class { * Sanitize a room ID by removing anything that isn't alphanumeric or `-`. * Shouldn't actually do anything except against malicious input. */ -function toRoomid(roomid: string) { +export function toRoomid(roomid: string) { return roomid.replace(/[^a-zA-Z0-9-]+/g, '').toLowerCase(); } -function toName(name: any) { +export function toName(name: any) { if (typeof name !== 'string' && typeof name !== 'number') return ''; name = ('' + name).replace(/[\|\s\[\]\,\u202e]+/g, ' ').trim(); if (name.length > 18) name = name.substr(0, 18).trim(); @@ -148,7 +219,7 @@ function toName(name: any) { return name; } -interface SpriteData { +export interface SpriteData { w: number; h: number; y?: number; @@ -161,7 +232,7 @@ interface SpriteData { shiny?: boolean; } -interface TeambuilderSpriteData { +export interface TeambuilderSpriteData { x: number; y: number; spriteDir: string; @@ -169,13 +240,18 @@ interface TeambuilderSpriteData { shiny?: boolean; } -const Dex = new class implements ModdedDex { +export const Dex = new class implements ModdedDex { + readonly Ability = Ability; + readonly Item = Item; + readonly Move = Move; + readonly Species = Species; + readonly gen = 9; readonly modid = 'gen9' as ID; readonly cache = null!; - readonly statNames: ReadonlyArray = ['hp', 'atk', 'def', 'spa', 'spd', 'spe']; - readonly statNamesExceptHP: ReadonlyArray = ['atk', 'def', 'spa', 'spd', 'spe']; + readonly statNames: ReadonlyArray = ['hp', 'atk', 'def', 'spa', 'spd', 'spe']; + readonly statNamesExceptHP: ReadonlyArray = ['atk', 'def', 'spa', 'spd', 'spe']; pokeballs: string[] | null = null; @@ -476,7 +552,7 @@ const Dex = new class implements ModdedDex { getSpriteData(pokemon: Pokemon | Species | string, isFront: boolean, options: { gen?: number, shiny?: boolean, - gender?: GenderName, + gender?: Dex.GenderName, afd?: boolean, noScale?: boolean, mod?: string, @@ -705,7 +781,7 @@ const Dex = new class implements ModdedDex { return num; } - getPokemonIcon(pokemon: string | Pokemon | ServerPokemon | PokemonSet | null, facingLeft?: boolean) { + getPokemonIcon(pokemon: string | Pokemon | ServerPokemon | Dex.PokemonSet | null, facingLeft?: boolean) { if (pokemon === 'pokeball') { return `background:transparent url(${Dex.resourcePrefix}sprites/pokemonicons-pokeball-sheet.png) no-repeat scroll -0px 4px`; } else if (pokemon === 'pokeball-statused') { @@ -843,7 +919,7 @@ const Dex = new class implements ModdedDex { } }; -class ModdedDex { +export class ModdedDex { readonly gen: number; readonly modid: ID; readonly cache = { @@ -851,7 +927,7 @@ class ModdedDex { Items: {} as any as {[k: string]: Item}, Abilities: {} as any as {[k: string]: Ability}, Species: {} as any as {[k: string]: Species}, - Types: {} as any as {[k: string]: Effect}, + Types: {} as any as {[k: string]: Dex.Effect}, }; pokeballs: string[] | null = null; constructor(modid: ID) { @@ -997,7 +1073,7 @@ class ModdedDex { }; types = { - get: (name: string): Effect => { + get: (name: string): Dex.Effect => { const id = toID(name) as ID; name = id.substr(0, 1).toUpperCase() + id.substr(1); @@ -1035,7 +1111,7 @@ class ModdedDex { } } -const Teams = new class { +export const Teams = new class { unpack(buf: string) { if (!buf) return []; @@ -1044,7 +1120,7 @@ const Teams = new class { let j = 0; while (true) { - const set: PokemonSet = {} as any; + const set: Dex.PokemonSet = {} as any; team.push(set); // name @@ -1079,7 +1155,7 @@ const Teams = new class { // nature j = buf.indexOf('|', i); - set.nature = buf.substring(i, j) as NatureName; + set.nature = buf.substring(i, j) as Dex.NatureName; if (set.nature as any === 'undefined') delete set.nature; i = j + 1; @@ -1155,7 +1231,7 @@ const Teams = new class { return team; } - export(team: PokemonSet[] | string, gen: number, hidestats = false) { + export(team: Dex.PokemonSet[] | string, gen: number, hidestats = false) { if (!team) return ''; if (typeof team === 'string') { if (team.indexOf('\n') >= 0) return team; @@ -1205,7 +1281,7 @@ const Teams = new class { if (!hidestats) { let first = true; if (curSet.evs) { - let j: StatName; + let j: Dex.StatName; for (j in BattleStatNames) { if (!curSet.evs[j]) continue; if (first) { @@ -1234,7 +1310,7 @@ const Teams = new class { alert(move + " is not a valid Hidden Power type."); continue; } - let stat: StatName; + let stat: Dex.StatName; for (stat in BattleStatNames) { if ((curSet.ivs[stat] === undefined ? 31 : curSet.ivs[stat]) !== (Dex.types.get(hpType).HPivs?.[stat] || 31)) { defaultIvs = false; @@ -1244,7 +1320,7 @@ const Teams = new class { } } if (defaultIvs && !hpType) { - let stat: StatName; + let stat: Dex.StatName; for (stat in BattleStatNames) { if (curSet.ivs[stat] !== 31 && curSet.ivs[stat] !== undefined) { defaultIvs = false; @@ -1253,7 +1329,7 @@ const Teams = new class { } } if (!defaultIvs) { - let stat: StatName; + let stat: Dex.StatName; for (stat in BattleStatNames) { if (typeof curSet.ivs[stat] === 'undefined' || isNaN(curSet.ivs[stat]) || curSet.ivs[stat] === 31) continue; if (first) { diff --git a/play.pokemonshowdown.com/src/battle-log.ts b/play.pokemonshowdown.com/src/battle-log.ts index 44edcd0e88..e340028631 100644 --- a/play.pokemonshowdown.com/src/battle-log.ts +++ b/play.pokemonshowdown.com/src/battle-log.ts @@ -13,7 +13,10 @@ * @license MIT */ +import type {Battle} from './battle'; import type {BattleScene} from './battle-animations'; +import {Dex, Teams, toID, toRoomid, toUserid, type ID} from './battle-dex'; +import {BattleTextParser, type Args, type KWArgs} from './battle-text-parser'; // Caja declare const html4: any; @@ -22,6 +25,7 @@ declare const html: any; // defined in battle-log-misc declare function MD5(input: string): string; declare function formatText(input: string, isTrusted?: boolean): string; +export {MD5, formatText}; export class BattleLog { elem: HTMLDivElement; diff --git a/play.pokemonshowdown.com/src/battle-scene-stub.ts b/play.pokemonshowdown.com/src/battle-scene-stub.ts index 7fc99892f5..1695c98060 100644 --- a/play.pokemonshowdown.com/src/battle-scene-stub.ts +++ b/play.pokemonshowdown.com/src/battle-scene-stub.ts @@ -1,6 +1,8 @@ import type {Pokemon, Side} from './battle'; import type {ScenePos, PokemonSprite} from './battle-animations'; import type {BattleLog} from './battle-log'; +import type {ID} from './battle-dex'; +import type {Args, KWArgs} from './battle-text-parser'; export class BattleSceneStub { animating: boolean = false; @@ -77,7 +79,9 @@ export class BattleSceneStub { afterMove(pokemon: Pokemon) { } } +declare const require: any; +declare const global: any; if (typeof require === 'function') { // in Node - (global as any).BattleSceneStub = BattleSceneStub; + global.BattleSceneStub = BattleSceneStub; } diff --git a/play.pokemonshowdown.com/src/battle-searchresults.tsx b/play.pokemonshowdown.com/src/battle-searchresults.tsx index f847b8f4de..433fe11eb4 100644 --- a/play.pokemonshowdown.com/src/battle-searchresults.tsx +++ b/play.pokemonshowdown.com/src/battle-searchresults.tsx @@ -7,7 +7,11 @@ * @license AGPLv3 */ -class PSSearchResults extends preact.Component<{search: DexSearch}> { +import preact from "../js/lib/preact"; +import {Dex, type ID} from "./battle-dex"; +import type {DexSearch, SearchRow} from "./battle-dex-search"; + +export class PSSearchResults extends preact.Component<{search: DexSearch}> { readonly URL_ROOT = `//${Config.routes.dex}/`; renderPokemonSortRow() { diff --git a/play.pokemonshowdown.com/src/battle-sound.ts b/play.pokemonshowdown.com/src/battle-sound.ts index 5307e73f97..c5fbab0493 100644 --- a/play.pokemonshowdown.com/src/battle-sound.ts +++ b/play.pokemonshowdown.com/src/battle-sound.ts @@ -1,3 +1,4 @@ +import {PS} from "./client-main"; export class BattleBGM { /** diff --git a/play.pokemonshowdown.com/src/battle-text-parser.ts b/play.pokemonshowdown.com/src/battle-text-parser.ts index 0ae6ad93e0..369ee403f7 100644 --- a/play.pokemonshowdown.com/src/battle-text-parser.ts +++ b/play.pokemonshowdown.com/src/battle-text-parser.ts @@ -8,13 +8,13 @@ * @license MIT */ -declare const BattleText: {[id: string]: {[templateName: string]: string}}; +import {toID, type ID} from "./battle-dex"; -type Args = [string, ...string[]]; -type KWArgs = {[kw: string]: string}; -type SideID = 'p1' | 'p2' | 'p3' | 'p4'; +export type Args = [string, ...string[]]; +export type KWArgs = {[kw: string]: string}; +export type SideID = 'p1' | 'p2' | 'p3' | 'p4'; -class BattleTextParser { +export class BattleTextParser { /** escaped for string.replace */ p1 = "Player 1"; /** escaped for string.replace */ @@ -1190,6 +1190,8 @@ class BattleTextParser { } } +declare const require: any; +declare const global: any; if (typeof require === 'function') { // in Node (global as any).BattleTextParser = BattleTextParser; diff --git a/play.pokemonshowdown.com/src/battle-tooltips.ts b/play.pokemonshowdown.com/src/battle-tooltips.ts index 814a500751..2e65aa6a49 100644 --- a/play.pokemonshowdown.com/src/battle-tooltips.ts +++ b/play.pokemonshowdown.com/src/battle-tooltips.ts @@ -8,6 +8,13 @@ * @license MIT */ +import {Pokemon, type Battle, type ServerPokemon} from "./battle"; +import {Dex, ModdedDex, toID, type ID} from "./battle-dex"; +import type {BattleScene} from "./battle-animations"; +import {BattleLog} from "./battle-log"; +import {BattleNatures} from "./battle-dex-data"; +import {BattleTextParser} from "./battle-text-parser"; + class ModifiableValue { value = 0; maxValue = 0; @@ -139,7 +146,7 @@ class ModifiableValue { } } -class BattleTooltips { +export class BattleTooltips { battle: Battle; constructor(battle: Battle) { @@ -463,13 +470,13 @@ class BattleTooltips { 'healreplacement': "Restores replacement's HP 100%", }; - getStatusZMoveEffect(move: Move) { + getStatusZMoveEffect(move: Dex.Move) { if (move.zMove!.effect! in BattleTooltips.zMoveEffects) { return BattleTooltips.zMoveEffects[move.zMove!.effect!]; } let boostText = ''; if (move.zMove!.boost) { - let boosts = Object.keys(move.zMove!.boost) as StatName[]; + let boosts = Object.keys(move.zMove!.boost) as Dex.StatName[]; boostText = boosts.map(stat => BattleTextParser.stat(stat) + ' +' + move.zMove!.boost![stat] ).join(', '); @@ -477,7 +484,7 @@ class BattleTooltips { return boostText; } - static zMoveTable: {[type in TypeName]: string} = { + static zMoveTable: {[type in Dex.TypeName]: string} = { Poison: "Acid Downpour", Fighting: "All-Out Pummeling", Dark: "Black Hole Eclipse", @@ -500,7 +507,7 @@ class BattleTooltips { "???": "", }; - static maxMoveTable: {[type in TypeName]: string} = { + static maxMoveTable: {[type in Dex.TypeName]: string} = { Poison: "Max Ooze", Fighting: "Max Knuckle", Dark: "Max Darkness", @@ -523,7 +530,7 @@ class BattleTooltips { "???": "", }; - getMaxMoveFromType(type: TypeName, gmaxMove?: string | Move) { + getMaxMoveFromType(type: Dex.TypeName, gmaxMove?: string | Dex.Move) { if (gmaxMove) { if (typeof gmaxMove === 'string') gmaxMove = this.battle.dex.moves.get(gmaxMove); if (type === gmaxMove.type) return gmaxMove; @@ -531,7 +538,9 @@ class BattleTooltips { return this.battle.dex.moves.get(BattleTooltips.maxMoveTable[type]); } - showMoveTooltip(move: Move, isZOrMax: string, pokemon: Pokemon, serverPokemon: ServerPokemon, gmaxMove?: Move) { + showMoveTooltip( + move: Dex.Move, isZOrMax: string, pokemon: Pokemon, serverPokemon: ServerPokemon, gmaxMove?: Dex.Move + ) { let text = ''; let zEffect = ''; @@ -552,13 +561,13 @@ class BattleTooltips { if (item.zMoveFrom === move.name) { move = this.battle.dex.moves.get(item.zMove as string); } else if (move.category === 'Status') { - move = new Move(move.id, "", { + move = new Dex.Move(move.id, "", { ...move, name: 'Z-' + move.name, }); zEffect = this.getStatusZMoveEffect(move); } else { - let moveName = BattleTooltips.zMoveTable[item.zMoveType as TypeName]; + let moveName = BattleTooltips.zMoveTable[item.zMoveType as Dex.TypeName]; let zMove = this.battle.dex.moves.get(moveName); let movePower = move.zMove!.basePower; // the different Hidden Power types don't have a Z power set, fall back on base move @@ -584,7 +593,7 @@ class BattleTooltips { break; } } - move = new Move(zMove.id, zMove.name, { + move = new Dex.Move(zMove.id, zMove.name, { ...zMove, category: move.category, basePower: movePower, @@ -598,7 +607,7 @@ class BattleTooltips { let maxMove = this.getMaxMoveFromType(moveType, gmaxMove); const basePower = ['gmaxdrumsolo', 'gmaxfireball', 'gmaxhydrosnipe'].includes(maxMove.id) ? maxMove.basePower : move.maxMove.basePower; - move = new Move(maxMove.id, maxMove.name, { + move = new Dex.Move(maxMove.id, maxMove.name, { ...maxMove, category: move.category, basePower, @@ -608,7 +617,7 @@ class BattleTooltips { } if (categoryDiff) { - move = new Move(move.id, move.name, { + move = new Dex.Move(move.id, move.name, { ...move, category, }); @@ -1437,7 +1446,7 @@ class BattleTooltips { return `${bullet} ${move.name} ${showKnown ? ' (revealed)' : ''}`; } - ppUsed(move: Move, pokemon: Pokemon) { + ppUsed(move: Dex.Move, pokemon: Pokemon) { for (let [moveName, ppUsed] of pokemon.moveTrack) { if (moveName.charAt(0) === '*') moveName = moveName.substr(1); if (move.name === moveName) return ppUsed; @@ -1507,7 +1516,9 @@ class BattleTooltips { /** * Gets the proper current type for moves with a variable type. */ - getMoveType(move: Move, value: ModifiableValue, forMaxMove?: boolean | Move): [TypeName, 'Physical' | 'Special' | 'Status'] { + getMoveType( + move: Dex.Move, value: ModifiableValue, forMaxMove?: boolean | Dex.Move + ): [Dex.TypeName, 'Physical' | 'Special' | 'Status'] { const pokemon = value.pokemon; const serverPokemon = value.serverPokemon; @@ -1570,7 +1581,7 @@ class BattleTooltips { } } if (move.id === 'terablast' && pokemon.terastallized) { - moveType = pokemon.terastallized as TypeName; + moveType = pokemon.terastallized as Dex.TypeName; } if (move.id === 'terastarstorm' && pokemon.getSpeciesForme() === 'Terapagos-Stellar') { moveType = 'Stellar'; @@ -1702,7 +1713,7 @@ class BattleTooltips { } // Gets the current accuracy for a move. - getMoveAccuracy(move: Move, value: ModifiableValue, target?: Pokemon) { + getMoveAccuracy(move: Dex.Move, value: ModifiableValue, target?: Pokemon) { value.reset(move.accuracy === true ? 0 : move.accuracy, true); let pokemon = value.pokemon!; @@ -1847,7 +1858,7 @@ class BattleTooltips { // Gets the proper current base power for moves which have a variable base power. // Takes into account the target for some moves. // If it is unsure of the actual base power, it gives an estimate. - getMoveBasePower(move: Move, moveType: TypeName, value: ModifiableValue, target: Pokemon | null = null) { + getMoveBasePower(move: Dex.Move, moveType: Dex.TypeName, value: ModifiableValue, target: Pokemon | null = null) { const pokemon = value.pokemon!; const serverPokemon = value.serverPokemon; @@ -2294,14 +2305,14 @@ class BattleTooltips { return value; } - static incenseTypes: {[itemName: string]: TypeName} = { + static incenseTypes: {[itemName: string]: Dex.TypeName} = { 'Odd Incense': 'Psychic', 'Rock Incense': 'Rock', 'Rose Incense': 'Grass', 'Sea Incense': 'Water', 'Wave Incense': 'Water', }; - static itemTypes: {[itemName: string]: TypeName} = { + static itemTypes: {[itemName: string]: Dex.TypeName} = { 'Black Belt': 'Fighting', 'Black Glasses': 'Dark', 'Charcoal': 'Fire', @@ -2329,7 +2340,7 @@ class BattleTooltips { 'Giratina': ['Griseous Core', 'Griseous Orb'], 'Venomicon': ['Vile Vial'], }; - static orbTypes: {[itemName: string]: TypeName[]} = { + static orbTypes: {[itemName: string]: Dex.TypeName[]} = { 'Soul Dew': ['Psychic', 'Dragon'], 'Adamant Crystal': ['Steel', 'Dragon'], 'Adamant Orb': ['Steel', 'Dragon'], @@ -2346,7 +2357,7 @@ class BattleTooltips { 'Struggle', 'Water Pledge', ]; - getItemBoost(move: Move, value: ModifiableValue, moveType: TypeName) { + getItemBoost(move: Dex.Move, value: ModifiableValue, moveType: Dex.TypeName) { let item = this.battle.dex.items.get(value.serverPokemon.item); let itemName = item.name; let moveName = move.name; @@ -2411,14 +2422,14 @@ class BattleTooltips { return value; } - getPokemonTypes(pokemon: Pokemon | ServerPokemon, preterastallized = false): ReadonlyArray { + getPokemonTypes(pokemon: Pokemon | ServerPokemon, preterastallized = false): ReadonlyArray { if (!(pokemon as Pokemon).getTypes) { return this.battle.dex.species.get(pokemon.speciesForme).types; } return (pokemon as Pokemon).getTypeList(undefined, preterastallized); } - pokemonHasType(pokemon: Pokemon | ServerPokemon, type: TypeName, types?: ReadonlyArray) { + pokemonHasType(pokemon: Pokemon | ServerPokemon, type: Dex.TypeName, types?: ReadonlyArray) { if (!types) types = this.getPokemonTypes(pokemon); for (const curType of types) { if (curType === type) return true; @@ -2501,48 +2512,6 @@ class BattleTooltips { } } -type StatsTable = {hp: number, atk: number, def: number, spa: number, spd: number, spe: number}; - -/** - * PokemonSet can be sparse, in which case that entry should be - * inferred from the rest of the set, according to sensible - * defaults. - */ -interface PokemonSet { - /** Defaults to species name (not including forme), like in games */ - name?: string; - species: string; - /** Defaults to no item */ - item?: string; - /** Defaults to no ability (error in Gen 3+) */ - ability?: string; - moves: string[]; - /** Defaults to no nature (error in Gen 3+) */ - nature?: NatureName; - /** Defaults to random legal gender, NOT subject to gender ratios */ - gender?: string; - /** Defaults to flat 252's (200's/0's in Let's Go) (error in gen 3+) */ - evs?: Partial; - /** Defaults to whatever makes sense - flat 31's unless you have Gyro Ball etc */ - ivs?: StatsTable; - /** Defaults as you'd expect (100 normally, 50 in VGC-likes, 5 in LC) */ - level?: number; - /** Defaults to no (error if shiny event) */ - shiny?: boolean; - /** Defaults to 255 unless you have Frustration, in which case 0 */ - happiness?: number; - /** Defaults to event required ball, otherwise Poké Ball */ - pokeball?: string; - /** Defaults to the type of your Hidden Power in Moves, otherwise Dark */ - hpType?: string; - /** Defaults to 10 */ - dynamaxLevel?: number; - /** Defaults to no (can only be yes for certain Pokemon) */ - gigantamax?: boolean; - /** Defaults to the primary type */ - teraType?: string; -} - class BattleStatGuesser { formatid: ID; dex: ModdedDex; @@ -2565,18 +2534,18 @@ class BattleStatGuesser { this.supportsEVs = !this.formatid.includes('letsgo'); this.supportsAVs = !this.supportsEVs && this.formatid.endsWith('norestrictions'); } - guess(set: PokemonSet) { + guess(set: Dex.PokemonSet) { let role = this.guessRole(set); let comboEVs = this.guessEVs(set, role); let evs = {hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0}; for (let stat in evs) { - evs[stat as StatName] = comboEVs[stat as StatName] || 0; + evs[stat as Dex.StatName] = comboEVs[stat as Dex.StatName] || 0; } let plusStat = comboEVs.plusStat || ''; let minusStat = comboEVs.minusStat || ''; return {role, evs, plusStat, minusStat, moveCount: this.moveCount, hasMove: this.hasMove}; } - guessRole(set: PokemonSet) { + guessRole(set: Dex.PokemonSet) { if (!set) return '?'; if (!set.moves) return '?'; @@ -2855,7 +2824,7 @@ class BattleStatGuesser { if (specialBulk >= physicalBulk) return 'Specially Defensive'; return 'Physically Defensive'; } - ensureMinEVs(evs: StatsTable, stat: StatName, min: number, evTotal: number) { + ensureMinEVs(evs: Dex.StatsTable, stat: Dex.StatName, min: number, evTotal: number) { if (!evs[stat]) evs[stat] = 0; let diff = min - evs[stat]; if (diff <= 0) return evTotal; @@ -2867,7 +2836,7 @@ class BattleStatGuesser { } if (diff <= 0) return evTotal; let evPriority = {def: 1, spd: 1, hp: 1, atk: 1, spa: 1, spe: 1}; - let prioStat: StatName; + let prioStat: Dex.StatName; for (prioStat in evPriority) { if (prioStat === stat) continue; if (evs[prioStat] && evs[prioStat] > 128) { @@ -2878,7 +2847,7 @@ class BattleStatGuesser { } return evTotal; // can't do it :( } - ensureMaxEVs(evs: StatsTable, stat: StatName, min: number, evTotal: number) { + ensureMaxEVs(evs: Dex.StatsTable, stat: Dex.StatName, min: number, evTotal: number) { if (!evs[stat]) evs[stat] = 0; let diff = evs[stat] - min; if (diff <= 0) return evTotal; @@ -2886,7 +2855,9 @@ class BattleStatGuesser { evTotal -= diff; return evTotal; // can't do it :( } - guessEVs(set: PokemonSet, role: string): Partial & {plusStat?: StatName | '', minusStat?: StatName | ''} { + guessEVs( + set: Dex.PokemonSet, role: string + ): Partial & {plusStat?: Dex.StatName | '', minusStat?: Dex.StatName | ''} { if (!set) return {}; if (role === '?') return {}; let species = this.dex.species.get(set.species || set.name!); @@ -2895,13 +2866,13 @@ class BattleStatGuesser { let hasMove = this.hasMove; let moveCount = this.moveCount; - let evs: StatsTable & {plusStat?: StatName | '', minusStat?: StatName | ''} = { + let evs: Dex.StatsTable & {plusStat?: Dex.StatName | '', minusStat?: Dex.StatName | ''} = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0, }; - let plusStat: StatName | '' = ''; - let minusStat: StatName | '' = ''; + let plusStat: Dex.StatName | '' = ''; + let minusStat: Dex.StatName | '' = ''; - let statChart: {[role: string]: [StatName, StatName]} = { + let statChart: {[role: string]: [Dex.StatName, Dex.StatName]} = { 'Bulky Band': ['atk', 'hp'], 'Fast Band': ['spe', 'atk'], 'Bulky Specs': ['spa', 'hp'], @@ -2963,7 +2934,7 @@ class BattleStatGuesser { evs[primaryStat] = ev; evTotal += ev; - let secondaryStat: StatName | null = statChart[role][1]; + let secondaryStat: Dex.StatName | null = statChart[role][1]; if (secondaryStat === 'hp' && set.level && set.level < 20) secondaryStat = 'spd'; stat = this.getStat(secondaryStat, set, 252, plusStat === secondaryStat ? 1.1 : 1.0); ev = 252; @@ -3106,7 +3077,7 @@ class BattleStatGuesser { return evs; } - getStat(stat: StatName, set: PokemonSet, evOverride?: number, natureOverride?: number) { + getStat(stat: Dex.StatName, set: Dex.PokemonSet, evOverride?: number, natureOverride?: number) { let species = this.dex.species.get(set.species); if (!species.exists) return 0; @@ -3146,7 +3117,7 @@ class BattleStatGuesser { } } -function BattleStatOptimizer(set: PokemonSet, formatid: ID) { +function BattleStatOptimizer(set: Dex.PokemonSet, formatid: ID) { if (!set.evs) return null; const dex = Dex.mod(formatid.slice(0, 4) as ID); @@ -3160,7 +3131,7 @@ function BattleStatOptimizer(set: PokemonSet, formatid: ID) { const species = dex.species.get(set.species); const level = set.level || 100; - const getStat = (stat: StatNameExceptHP, ev: number, nature: Nature) => { + const getStat = (stat: Dex.StatNameExceptHP, ev: number, nature: Dex.Nature) => { const baseStat = species.baseStats[stat]; const iv = set.ivs?.[stat] || 31; let val = ~~(~~(2 * baseStat + iv + ~~(ev / 4)) * level / 100 + 5); @@ -3181,7 +3152,7 @@ function BattleStatOptimizer(set: PokemonSet, formatid: ID) { spd: getStat('spd', set.evs.spd || 0, origNature), spe: getStat('spe', set.evs.spe || 0, origNature), }; - const getMinEVs = (stat: StatNameExceptHP, nature: Nature) => { + const getMinEVs = (stat: Dex.StatNameExceptHP, nature: Dex.Nature) => { let ev = 0; while (getStat(stat, ev, nature) < origStats[stat]) { ev += 4; @@ -3252,9 +3223,9 @@ function BattleStatOptimizer(set: PokemonSet, formatid: ID) { if (bestPlus && savedEVs >= 0) { const newSpread: { - evs: Partial, - plus?: StatNameExceptHP, - minus?: StatNameExceptHP, + evs: Partial, + plus?: Dex.StatNameExceptHP, + minus?: Dex.StatNameExceptHP, } = {evs: {...origSpread.evs}, plus: bestPlus, minus: bestMinus}; if (bestPlus !== origNature.plus || bestMinus !== origNature.minus) { newSpread.evs[bestPlus] = bestPlusMinEVs!; @@ -3291,6 +3262,8 @@ function BattleStatOptimizer(set: PokemonSet, formatid: ID) { return null; } +declare const require: any; +declare const global: any; if (typeof require === 'function') { // in Node (global as any).BattleStatGuesser = BattleStatGuesser; diff --git a/play.pokemonshowdown.com/src/battle.ts b/play.pokemonshowdown.com/src/battle.ts index 6a298afcef..93a9dab076 100644 --- a/play.pokemonshowdown.com/src/battle.ts +++ b/play.pokemonshowdown.com/src/battle.ts @@ -27,9 +27,12 @@ * @license MIT */ +// import $ from 'jquery'; import {BattleSceneStub} from './battle-scene-stub'; import {BattleLog} from './battle-log'; import {BattleScene, PokemonSprite, BattleStatusAnims} from './battle-animations'; +import {Dex, Teams, toID, toUserid, type ID, type ModdedDex} from './battle-dex'; +import {BattleTextParser, type Args, type KWArgs, type SideID} from './battle-text-parser'; /** [id, element?, ...misc] */ export type EffectState = any[] & {0: ID}; @@ -79,7 +82,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { hp = 0; maxhp = 1000; level = 100; - gender: GenderName = 'N'; + gender: Dex.GenderName = 'N'; shiny = false; hpcolor: HPColor = 'g'; @@ -94,7 +97,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { teraType = ''; boosts: {[stat: string]: number} = {}; - status: StatusName | 'tox' | '' | '???' = ''; + status: Dex.StatusName | 'tox' | '' | '???' = ''; statusStage = 0; volatiles: {[effectid: string]: EffectState} = {}; turnstatuses: {[effectid: string]: EffectState} = {}; @@ -361,7 +364,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { this.baseAbility = ability; } } - getBoost(boostStat: BoostStatName) { + getBoost(boostStat: Dex.BoostStatName) { let boostStatTable = { atk: 'Atk', def: 'Def', @@ -409,7 +412,7 @@ export class Pokemon implements PokemonDetails, PokemonHealth { let autotomizeFactor = this.volatiles.autotomize?.[1] * 100 || 0; return Math.max(this.getSpecies(serverPokemon).weightkg - autotomizeFactor, 0.1); } - getBoostType(boostStat: BoostStatName) { + getBoostType(boostStat: Dex.BoostStatName) { if (!this.boosts[boostStat]) return 'neutral'; if (this.boosts[boostStat] > 0) return 'good'; return 'bad'; @@ -474,10 +477,10 @@ export class Pokemon implements PokemonDetails, PokemonHealth { this.removeVolatile('typeadd' as ID); } } - getTypes(serverPokemon?: ServerPokemon, preterastallized = false): [ReadonlyArray, TypeName | ''] { - let types: ReadonlyArray; + getTypes(serverPokemon?: ServerPokemon, preterastallized = false): [ReadonlyArray, Dex.TypeName | ''] { + let types: ReadonlyArray; if (!preterastallized && this.terastallized && this.terastallized !== 'Stellar') { - types = [this.terastallized as TypeName]; + types = [this.terastallized as Dex.TypeName]; } else if (this.volatiles.typechange) { types = this.volatiles.typechange[1].split('/'); } else { @@ -675,7 +678,7 @@ export class Side { if (this.foe && this.avatar === this.foe.avatar) this.rollTrainerSprites(); } } - addSideCondition(effect: Effect, persist: boolean) { + addSideCondition(effect: Dex.Effect, persist: boolean) { let condition = effect.id; if (this.sideConditions[condition]) { if (condition === 'spikes' || condition === 'toxicspikes') { @@ -970,7 +973,7 @@ export interface PokemonDetails { speciesForme: string; level: number; shiny: boolean; - gender: GenderName | ''; + gender: Dex.GenderName | ''; ident: string; terastallized: string; searchid: string; @@ -979,7 +982,7 @@ export interface PokemonHealth { hp: number; maxhp: number; hpcolor: HPColor | ''; - status: StatusName | 'tox' | '' | '???'; + status: Dex.StatusName | 'tox' | '' | '???'; fainted?: boolean; } export interface ServerPokemon extends PokemonDetails, PokemonHealth { @@ -1389,7 +1392,7 @@ export class Battle { this.turnsSinceMoved = 0; this.scene.updateAcceleration(); } - changeWeather(weatherName: string, poke?: Pokemon, isUpkeep?: boolean, ability?: Effect) { + changeWeather(weatherName: string, poke?: Pokemon, isUpkeep?: boolean, ability?: Dex.Effect) { let weather = toID(weatherName); if (!weather || weather === 'none') { weather = '' as ID; @@ -1472,7 +1475,7 @@ export class Battle { } this.scene.updateWeather(); } - useMove(pokemon: Pokemon, move: Move, target: Pokemon | null, kwArgs: KWArgs) { + useMove(pokemon: Pokemon, move: Dex.Move, target: Pokemon | null, kwArgs: KWArgs) { let fromeffect = Dex.getEffect(kwArgs.from); this.activateAbility(pokemon, fromeffect); pokemon.clearMovestatuses(); @@ -1486,7 +1489,7 @@ export class Battle { let callerMoveForPressure = null; // will not include effects that are conditions named after moves like Magic Coat and Snatch, which is good if (fromeffect.id && kwArgs.from.startsWith("move:")) { - callerMoveForPressure = fromeffect as Move; + callerMoveForPressure = fromeffect as Dex.Move; } if (!fromeffect.id || callerMoveForPressure || fromeffect.id === 'pursuit') { let moveName = move.name; @@ -1546,7 +1549,7 @@ export class Battle { pokemon.side.wisher = pokemon; } } - animateMove(pokemon: Pokemon, move: Move, target: Pokemon | null, kwArgs: KWArgs) { + animateMove(pokemon: Pokemon, move: Dex.Move, target: Pokemon | null, kwArgs: KWArgs) { this.activeMoveIsSpread = kwArgs.spread; if (this.seeking !== null || kwArgs.still) return; @@ -1587,7 +1590,7 @@ export class Battle { this.scene.runMoveAnim(usedMove.id, targets); } - cantUseMove(pokemon: Pokemon, effect: Effect, move: Move, kwArgs: KWArgs) { + cantUseMove(pokemon: Pokemon, effect: Dex.Effect, move: Dex.Move, kwArgs: KWArgs) { pokemon.clearMovestatuses(); this.scene.updateStatbar(pokemon); if (effect.id in BattleStatusAnims) { @@ -1632,7 +1635,7 @@ export class Battle { this.scene.animReset(pokemon); } - activateAbility(pokemon: Pokemon | null, effectOrName: Effect | string, isNotBase?: boolean) { + activateAbility(pokemon: Pokemon | null, effectOrName: Dex.Effect | string, isNotBase?: boolean) { if (!pokemon || !effectOrName) return; if (typeof effectOrName !== 'string') { if (effectOrName.effectType !== 'Ability') return; @@ -1810,7 +1813,7 @@ export class Battle { } case '-boost': { let poke = this.getPokemon(args[1])!; - let stat = args[2] as BoostStatName; + let stat = args[2] as Dex.BoostStatName; if (this.gen === 1 && stat === 'spd') break; if (this.gen === 1 && stat === 'spa') stat = 'spc'; let amount = parseInt(args[3], 10); @@ -1837,7 +1840,7 @@ export class Battle { } case '-unboost': { let poke = this.getPokemon(args[1])!; - let stat = args[2] as BoostStatName; + let stat = args[2] as Dex.BoostStatName; if (this.gen === 1 && stat === 'spd') break; if (this.gen === 1 && stat === 'spa') stat = 'spc'; let amount = parseInt(args[3], 10); @@ -1862,7 +1865,7 @@ export class Battle { } case '-setboost': { let poke = this.getPokemon(args[1])!; - let stat = args[2] as BoostStatName; + let stat = args[2] as Dex.BoostStatName; let amount = parseInt(args[3], 10); poke.boosts[stat] = amount; this.scene.resultAnim(poke, poke.getBoost(stat), (amount > 0 ? 'good' : 'bad')); @@ -2128,7 +2131,7 @@ export class Battle { let poke = this.getPokemon(args[1])!; let effect = Dex.getEffect(kwArgs.from); let ofpoke = this.getPokemon(kwArgs.of) || poke; - poke.status = args[2] as StatusName; + poke.status = args[2] as Dex.StatusName; this.activateAbility(ofpoke || poke, effect); if (effect.effectType === 'Item') { ofpoke.item = effect.name; @@ -3195,7 +3198,7 @@ export class Battle { splitDetails.pop(); } if (splitDetails[splitDetails.length - 1] === 'M' || splitDetails[splitDetails.length - 1] === 'F') { - output.gender = splitDetails[splitDetails.length - 1] as GenderName; + output.gender = splitDetails[splitDetails.length - 1] as Dex.GenderName; splitDetails.pop(); } if (splitDetails[1]) { @@ -3947,6 +3950,8 @@ export class Battle { } } +declare const require: any; +declare const global: any; if (typeof require === 'function') { // in Node (global as any).Battle = Battle; diff --git a/play.pokemonshowdown.com/src/client-connection.ts b/play.pokemonshowdown.com/src/client-connection.ts index bc2579cba0..7dac3cf621 100644 --- a/play.pokemonshowdown.com/src/client-connection.ts +++ b/play.pokemonshowdown.com/src/client-connection.ts @@ -5,9 +5,11 @@ * @license MIT */ +import {PS} from "./client-main"; + declare var SockJS: any; -class PSConnection { +export class PSConnection { socket: any = null; connected = false; queue = [] as string[]; @@ -57,7 +59,7 @@ class PSConnection { PS.connection = new PSConnection(); -const PSLoginServer = new class { +export const PSLoginServer = new class { query(data: PostData): Promise<{[k: string]: any} | null> { let url = '/~~' + PS.server.id + '/action.php'; if (location.pathname.endsWith('.html')) { @@ -160,7 +162,7 @@ class NetRequest { } } -function Net(uri: string) { +export function Net(uri: string) { return new NetRequest(uri); } diff --git a/play.pokemonshowdown.com/src/client-core.ts b/play.pokemonshowdown.com/src/client-core.ts index ebb9cff35d..df91bd4a2f 100644 --- a/play.pokemonshowdown.com/src/client-core.ts +++ b/play.pokemonshowdown.com/src/client-core.ts @@ -84,7 +84,7 @@ if (!window.console) { const PSURL = `${document.location!.protocol !== 'http:' ? 'https:' : ''}//${Config.routes.client}/`; -class PSSubscription { +export class PSSubscription { observable: PSModel | PSStreamModel; listener: (value?: any) => void; constructor(observable: PSModel | PSStreamModel, listener: (value?: any) => void) { @@ -102,7 +102,7 @@ class PSSubscription { * spec - just the parts we use. PSModel just notifies subscribers of * updates - a simple model for React. */ -class PSModel { +export class PSModel { subscriptions = [] as PSSubscription[]; subscribe(listener: () => void) { const subscription = new PSSubscription(this, listener); @@ -128,7 +128,7 @@ class PSModel { * which hold state, PSStreamModels give state directly to views, * so that the model doesn't need to hold a redundant copy of state. */ -class PSStreamModel { +export class PSStreamModel { subscriptions = [] as PSSubscription[]; updates = [] as T[]; subscribe(listener: (value: T) => void) { diff --git a/play.pokemonshowdown.com/src/client-main.ts b/play.pokemonshowdown.com/src/client-main.ts index 5309378df2..2fd42cd9f9 100644 --- a/play.pokemonshowdown.com/src/client-main.ts +++ b/play.pokemonshowdown.com/src/client-main.ts @@ -9,6 +9,14 @@ * @license AGPLv3 */ +import { PSConnection, PSLoginServer } from './client-connection'; +import {PSModel, PSStreamModel} from './client-core'; +import type {PSRouter} from './panels'; +import type {ChatRoom} from './panel-chat'; +import type {MainMenuRoom} from './panel-mainmenu'; +import {toID, type ID} from './battle-dex'; +import {BattleTextParser, type Args} from './battle-text-parser'; + /********************************************************************** * Prefs *********************************************************************/ @@ -16,7 +24,7 @@ /** * String that contains only lowercase alphanumeric characters. */ -type RoomID = string & {__isRoomID: true}; +export type RoomID = string & {__isRoomID: true}; const PSPrefsDefaults: {[key: string]: any} = {}; @@ -146,7 +154,7 @@ class PSPrefs extends PSStreamModel { * Teams *********************************************************************/ -interface Team { +export interface Team { name: string; format: ID; packedTeam: string; @@ -409,7 +417,7 @@ class PSServer { type PSRoomLocation = 'left' | 'right' | 'popup' | 'mini-window' | 'modal-popup' | 'semimodal-popup'; -interface RoomOptions { +export interface RoomOptions { id: RoomID; title?: string; type?: string; @@ -436,7 +444,7 @@ interface PSNotificationState { * As a PSStreamModel, PSRoom can emit `Args` to mean "we received a message", * and `null` to mean "tell Preact to re-render this room" */ -class PSRoom extends PSStreamModel implements RoomOptions { +export class PSRoom extends PSStreamModel implements RoomOptions { id: RoomID; title = ""; type = ''; @@ -580,7 +588,7 @@ type RoomType = {Model?: typeof PSRoom, Component: any, title?: string}; * - changing which room is focused * - changing the width of the left room, in two-panel mode */ -const PS = new class extends PSModel { +export const PS = new class extends PSModel { down: string | boolean = false; prefs = new PSPrefs(); diff --git a/play.pokemonshowdown.com/src/globals.d.ts b/play.pokemonshowdown.com/src/globals.d.ts index b81224f6be..c3e53c2892 100644 --- a/play.pokemonshowdown.com/src/globals.d.ts +++ b/play.pokemonshowdown.com/src/globals.d.ts @@ -1,6 +1,8 @@ // dex data /////////// +declare var BattleText: {[id: string]: {[templateName: string]: string}}; +declare var BattleFormats: {[id: string]: import('./panel-teamdropdown').FormatData}; declare var BattlePokedex: any; declare var BattleMovedex: any; declare var BattleAbilities: any; @@ -9,6 +11,7 @@ declare var BattleAliases: any; declare var BattleStatuses: any; declare var BattlePokemonSprites: any; declare var BattlePokemonSpritesBW: any; +declare var NonBattleGames: {[id: string]: string}; // PS globals ///////////// @@ -25,15 +28,15 @@ interface Window { // Temporary globals (exported from modules, used by non-module files) -// When creating now module files, these should all be commented out +// When creating new module files, these should all be commented out // to make sure they're not being used globally in modules. -declare var Battle: typeof import('./battle').Battle; -type Battle = import('./battle').Battle; -declare var BattleScene: typeof import('./battle-animations').BattleScene; -type BattleScene = import('./battle-animations').BattleScene; -declare var Pokemon: typeof import('./battle').Pokemon; -type Pokemon = import('./battle').Pokemon; -type ServerPokemon = import('./battle').ServerPokemon; -declare var BattleLog: typeof import('./battle-log').BattleLog; -type BattleLog = import('./battle-log').BattleLog; +// declare var Battle: typeof import('./battle').Battle; +// type Battle = import('./battle').Battle; +// declare var BattleScene: typeof import('./battle-animations').BattleScene; +// type BattleScene = import('./battle-animations').BattleScene; +// declare var Pokemon: typeof import('./battle').Pokemon; +// type Pokemon = import('./battle').Pokemon; +// type ServerPokemon = import('./battle').ServerPokemon; +// declare var BattleLog: typeof import('./battle-log').BattleLog; +// type BattleLog = import('./battle-log').BattleLog; diff --git a/play.pokemonshowdown.com/src/panel-battle.tsx b/play.pokemonshowdown.com/src/panel-battle.tsx index e86ab9a3d8..e50890190d 100644 --- a/play.pokemonshowdown.com/src/panel-battle.tsx +++ b/play.pokemonshowdown.com/src/panel-battle.tsx @@ -5,8 +5,19 @@ * @license AGPLv3 */ -// import preact from "../js/lib/preact"; -// import {Battle} from "./battle"; +import preact from "../js/lib/preact"; +import {PS, PSRoom, type RoomOptions, type RoomID} from "./client-main"; +import {PSPanelWrapper, PSRoomPanel} from "./panels"; +import {ChatLog, ChatRoom, ChatTextEntry, ChatUserList} from "./panel-chat"; +import {FormatDropdown} from "./panel-mainmenu"; +import {Battle, Pokemon, type ServerPokemon} from "./battle"; +import {BattleScene} from "./battle-animations"; +import { Dex, toID } from "./battle-dex"; +import { + BattleChoiceBuilder, type BattleMoveRequest, type BattleRequest, type BattleRequestSideInfo, + type BattleSwitchRequest, type BattleTeamRequest +} from "./battle-choices"; +import type {Args} from "./battle-text-parser"; type BattleDesc = { id: RoomID, @@ -17,7 +28,7 @@ type BattleDesc = { p4?: string, }; -class BattlesRoom extends PSRoom { +export class BattlesRoom extends PSRoom { override readonly classType = 'battles'; /** null means still loading */ format = ''; @@ -173,7 +184,7 @@ class BattleDiv extends preact.Component { } function MoveButton(props: { - children: string, cmd: string, moveData: {pp: number, maxpp: number}, type: TypeName, tooltip: string, + children: string, cmd: string, moveData: {pp: number, maxpp: number}, type: Dex.TypeName, tooltip: string, }) { return
      ; } -function TeamBox(props: {team: Team | null, noLink?: boolean, button?: boolean}) { +export function TeamBox(props: {team: Team | null, noLink?: boolean, button?: boolean}) { const team = props.team; let contents; if (team) { @@ -725,7 +730,7 @@ class TeamDropdownPanel extends PSRoomPanel { } } -interface FormatData { +export interface FormatData { id: ID; name: string; team?: 'preset' | null; @@ -742,9 +747,9 @@ interface FormatData { effectType: 'Format'; } -declare var BattleFormats: {[id: string]: FormatData}; +declare const BattleFormats: {[id: string]: FormatData}; /** id:name */ -declare var NonBattleGames: {[id: string]: string}; +declare const NonBattleGames: {[id: string]: string}; class FormatDropdownPanel extends PSRoomPanel { gen = ''; diff --git a/play.pokemonshowdown.com/src/panel-topbar.tsx b/play.pokemonshowdown.com/src/panel-topbar.tsx index 205bba9181..e0a972087c 100644 --- a/play.pokemonshowdown.com/src/panel-topbar.tsx +++ b/play.pokemonshowdown.com/src/panel-topbar.tsx @@ -9,6 +9,13 @@ * @license AGPLv3 */ +import preact from "../js/lib/preact"; +import {PS, PSRoom, type RoomOptions, type RoomID} from "./client-main"; +import {PSMain, PSPanelWrapper, PSRoomPanel} from "./panels"; +import type {Battle} from "./battle"; +import {Dex, toRoomid, toUserid, type ID} from "./battle-dex"; +import {BattleLog} from "./battle-log"; + window.addEventListener('drop', e => { console.log('drop ' + e.dataTransfer!.dropEffect); const target = e.target as HTMLElement; @@ -33,7 +40,7 @@ window.addEventListener('dragover', e => { e.preventDefault(); }); -class PSHeader extends preact.Component<{style: {}}> { +export class PSHeader extends preact.Component<{style: {}}> { handleDragEnter = (e: DragEvent) => { console.log('dragenter ' + e.dataTransfer!.dropEffect); e.preventDefault(); @@ -260,7 +267,7 @@ preact.render(, document.body, document.getElementById('ps-frame')!); * User popup */ -class UserRoom extends PSRoom { +export class UserRoom extends PSRoom { override readonly classType = 'user'; userid: ID; name: string; @@ -352,8 +359,8 @@ class UserPanel extends PSRoomPanel { away = user.status.startsWith('!'); status = away ? user.status.slice(1) : user.status; } - return +
      {user.avatar !== '[loading]' && extends preact.Component<{room: T}> { +export class PSRoomPanel extends preact.Component<{room: T}> { subscriptions: PSSubscription[] = []; override componentDidMount() { if (PS.room === this.props.room) this.focus(); @@ -166,7 +175,7 @@ class PSRoomPanel extends preact.Component<{room: T}> } } -function PSPanelWrapper(props: { +export function PSPanelWrapper(props: { room: PSRoom, children: preact.ComponentChildren, scrollable?: boolean, width?: number | 'auto', }) { const room = props.room; @@ -192,7 +201,7 @@ function PSPanelWrapper(props: {
      ; } -class PSMain extends preact.Component { +export class PSMain extends preact.Component { constructor() { super(); PS.subscribe(() => this.forceUpdate()); @@ -513,6 +522,6 @@ class PSMain extends preact.Component { type PanelPosition = {top?: number, bottom?: number, left?: number, right?: number} | null; -function SanitizedHTML(props: {children: string}) { +export function SanitizedHTML(props: {children: string}) { return
      ; } diff --git a/tslint.json b/tslint.json index 280ac9e9a3..f793140a17 100644 --- a/tslint.json +++ b/tslint.json @@ -29,6 +29,7 @@ "new-parens": false, "no-bitwise": false, "no-console": false, + "no-namespace": [true, "allow-declarations"], "only-arrow-functions": false, "prefer-conditional-expression": false, "no-shadowed-variable": [true, {"temporalDeadZone": false}], From 3d4de8870685b972f4d757dfe98f48c9dfb1e553 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 19 Feb 2025 16:36:54 -0800 Subject: [PATCH 770/770] Correct Snowscape weather name --- play.pokemonshowdown.com/src/battle-animations.ts | 2 +- play.pokemonshowdown.com/src/battle-text-parser.ts | 5 +++++ play.pokemonshowdown.com/src/battle-tooltips.ts | 14 +++++++------- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index 1b18f73cdc..258b9e5048 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -958,7 +958,7 @@ export class BattleScene implements BattleSceneStub { primordialsea: 'Heavy Rain', sandstorm: 'Sandstorm', hail: 'Hail', - snow: 'Snow', + snowscape: 'Snow', deltastream: 'Strong Winds', }; weatherhtml = `${weatherNameTable[this.battle.weather] || this.battle.weather}`; diff --git a/play.pokemonshowdown.com/src/battle-text-parser.ts b/play.pokemonshowdown.com/src/battle-text-parser.ts index 369ee403f7..0e24274ee1 100644 --- a/play.pokemonshowdown.com/src/battle-text-parser.ts +++ b/play.pokemonshowdown.com/src/battle-text-parser.ts @@ -203,6 +203,11 @@ export class BattleTextParser { break; } + case '-weather': { + if (args[1] === 'Snow') args[1] = 'Snowscape'; + break; + } + case '-nothing': // OLD: |-nothing // NEW: |-activate||move:Splash diff --git a/play.pokemonshowdown.com/src/battle-tooltips.ts b/play.pokemonshowdown.com/src/battle-tooltips.ts index 2e65aa6a49..c169fb1cae 100644 --- a/play.pokemonshowdown.com/src/battle-tooltips.ts +++ b/play.pokemonshowdown.com/src/battle-tooltips.ts @@ -35,7 +35,7 @@ class ModifiableValue { this.itemName = this.battle.dex.items.get(serverPokemon.item).name; const ability = serverPokemon.ability || pokemon?.ability || serverPokemon.baseAbility; this.abilityName = this.battle.dex.abilities.get(ability).name; - this.weatherName = battle.weather === 'snow' ? 'Snow' : this.battle.dex.moves.get(battle.weather).exists ? + this.weatherName = this.battle.dex.moves.get(battle.weather).exists ? this.battle.dex.moves.get(battle.weather).name : this.battle.dex.abilities.get(battle.weather).name; } reset(value = 0, isAccuracy?: boolean) { @@ -588,7 +588,7 @@ export class BattleTooltips { zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Rock']); break; case 'hail': - case 'snow': + case 'snowscape': zMove = this.battle.dex.moves.get(BattleTooltips.zMoveTable['Ice']); break; } @@ -1116,13 +1116,13 @@ export class BattleTooltips { if (this.battle.gen >= 4 && this.pokemonHasType(pokemon, 'Rock') && weather === 'sandstorm') { stats.spd = Math.floor(stats.spd * 1.5); } - if (this.pokemonHasType(pokemon, 'Ice') && weather === 'snow') { + if (this.pokemonHasType(pokemon, 'Ice') && weather === 'snowscape') { stats.def = Math.floor(stats.def * 1.5); } if (ability === 'sandrush' && weather === 'sandstorm') { speedModifiers.push(2); } - if (ability === 'slushrush' && (weather === 'hail' || weather === 'snow')) { + if (ability === 'slushrush' && (weather === 'hail' || weather === 'snowscape')) { speedModifiers.push(2); } if (item !== 'utilityumbrella') { @@ -1275,7 +1275,7 @@ export class BattleTooltips { if (ability === 'misspelled') { stats.spa = Math.floor(stats.spa * 1.5); } - if (ability === 'fortifyingfrost' && weather === 'snow') { + if (ability === 'fortifyingfrost' && weather === 'snowscape') { stats.spa = Math.floor(stats.spa * 1.5); stats.spd = Math.floor(stats.spd * 1.5); } @@ -1295,7 +1295,7 @@ export class BattleTooltips { stats.def *= 2; } if (ability === 'climatechange') { - if (weather === 'snow') { + if (weather === 'snowscape') { stats.def = Math.floor(stats.def * 1.5); stats.spd = Math.floor(stats.spd * 1.5); } @@ -1564,7 +1564,7 @@ export class BattleTooltips { moveType = 'Rock'; break; case 'hail': - case 'snow': + case 'snowscape': moveType = 'Ice'; break; }