Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

PS replay converter source

By: a guest on Jun 16th, 2013  |  syntax: PHP  |  size: 54.68 KB  |  views: 41  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php
  2.  
  3. /*
  4.  
  5. License: CC0 (public domain)
  6.   <http://creativecommons.org/publicdomain/zero/1.0/>
  7.  
  8. This license DOES NOT extend to any other files of the Pokemon replay viewer.
  9.  
  10. */
  11.  
  12. include_once 'persist.lib.php';
  13. include_once 'replays.inc.php';
  14. include_once 'data/pokedex.inc.php';
  15. include_once 'data/typechart.inc.php';
  16.  
  17. function parseName($name)
  18. {
  19.         $monthTable = array('january' => '01', 'february' => '02', 'march' => '03', 'april' => '04', 'may' => '05', 'june' => '06', 'july' => '07', 'august' => '08', 'september' => '09', 'october' => '10', 'november' => '11', 'december' => '12');
  20.         if (substr($name, -5) === '.html') $name = substr($name,0,-5);
  21.         if (substr($name, -4) === '.htm') $name = substr($name,0,-4);
  22.         if (preg_match('/^(.*)\-\-([0-9]+) ([A-Z][a-z]+) ([0-9]+) at ([0-9]+)h([0-9]+)$/', $name, $matches))
  23.         {
  24.                 $name = trim($matches[1]).'--'.$matches[4].'-'.$monthTable[strtolower($matches[3])].'-'.$matches[2];
  25.         }
  26.         $name = str_replace(' ','-',$name);
  27.        
  28.         $name = preg_replace('/[^A-Za-z0-9-]+/', '', $name);
  29.         return $name;
  30. }
  31.  
  32. function startsRemove(&$str, $substr)
  33. {
  34.         if (substr($str, 0, strlen($substr)) === $substr)
  35.         {
  36.                 $str = substr($str, strlen($substr));
  37.                 return true;
  38.         }
  39.         return false;
  40. }
  41. function endsRemove(&$str, $substr)
  42. {
  43.         if (substr($str, -strlen($substr)) === $substr)
  44.         {
  45.                 $str = substr($str, 0, -strlen($substr));
  46.                 return true;
  47.         }
  48.         return false;
  49. }
  50. function startsWith($str, $substr)
  51. {
  52.         return (substr($str, 0, strlen($substr)) === $substr);
  53. }
  54. function endsWith($str, $substr)
  55. {
  56.         return (substr($str, -strlen($substr)) === $substr);
  57. }
  58. function uppercaseFirstLetter($str)
  59. {
  60.         // I am raging at PO replays for this.
  61.         return strtoupper(substr($str,0,1)).substr($str,1);
  62. }
  63. function lowercaseFirstLetter($str)
  64. {
  65.         // I am raging at PO replays for this.
  66.         return strtolower(substr($str,0,1)).substr($str,1);
  67. }
  68.         $pokemontable = array('Bandier' => 'ally-Bandier(Dodrio)', 'Scarfy' => 'ally-Scarfy(Dodrio)');
  69. function namePokemon($pokemon)
  70. {
  71.         global $pokemontable, $allpokemon, $currentpokemon;
  72.         $pokemonConv = $pokemon;
  73.         $pos = strrpos($pokemon, '(');
  74.         if ($pos) $pokemonConv = substr($pokemon, 0, $pos);
  75.         $pokemonConv = str_replace(' ', '', $pokemonConv);
  76.         $currentpokemon[$pokemonConv] = $pokemon;
  77. }
  78. function matchName($pokemon)
  79. {
  80.         global $currentpokemon;
  81.         foreach ($currentpokemon as $mpoke => $cpoke)
  82.         {
  83.                 startsRemove($mpoke,'ally-');
  84.                 startsRemove($mpoke,'foe-');
  85.                 if ($pokemon === $mpoke) return $mpoke;
  86.                 else if ($pokemon === uppercaseFirstLetter($mpoke)) return $mpoke;
  87.         }
  88.         return $pokemon;
  89. }
  90. function resolvePokemon($pokemon)
  91. {
  92.         global $convertNotDone, $allpokemon, $allyname, $playernames, $pokemontable, $lastPokemon, $returnNow, $currentpokemon;
  93.         if ($pokemontable[$pokemon])
  94.         {
  95.                 $currentpokemon[$pokemontable[$pokemon]] = $pokemontable[$pokemon];
  96.                 $lastPokemon = $pokemontable[$pokemon];
  97.                 return $pokemontable[$pokemon];
  98.         }
  99.         $pokeid = '';
  100.         //      echo '['.$playernames[0].'|'.$pokemon.']';
  101.         if (startsRemove($pokemon, "The foe's ") || startsRemove($pokemon, "the foe's "))
  102.         {
  103.                 $pokeid = $pokemon;
  104.                 $pokemon = 'foe-'.$pokemon;
  105.         }
  106.         else if (startsRemove($pokemon, $playernames[0]."'s ") || startsRemove($pokemon, uppercaseFirstLetter($playernames[0])."'s "))
  107.         {
  108.                 $pokeid = $pokemon;
  109.                 $pokemon = 'ally-'.$pokemon;
  110.         }
  111.         else if (startsRemove($pokemon, $playernames[1]."'s ") || startsRemove($pokemon, uppercaseFirstLetter($playernames[1])."'s "))
  112.         {
  113.                 $pokeid = $pokemon;
  114.                 $pokemon = 'foe-'.$pokemon;
  115.         }
  116.         else
  117.         {
  118.                 $pokeid = $pokemon;
  119.                 $pokemon = 'ally-'.matchName($pokemon);
  120.         }
  121.         $pokemon = str_replace(' ', '', $pokemon);
  122.         if ($convertNotDone && $pokeid && $allpokemon[$pokeid])
  123.         {
  124.                 if (substr($pokemon,0,4) === 'foe-')
  125.                 {
  126.                         $allyname = 'foeof-'.$allpokemon[$pokeid];
  127.                         $returnNow = true;
  128.                         return '';
  129.                 }
  130.                 $allyname = $allpokemon[$pokeid];
  131.                 $returnNow = true;
  132.                 return '';
  133.         }
  134.         $lastPokemon = $pokemon;
  135.        
  136.         if ($GLOBALS['BattlePokemon'][getSpecies($pokemon)]['number'] >= 494)
  137.         {
  138.                 $GLOBALS['gen'] = 5;
  139.         }
  140.         if ($GLOBALS['BattlePokemon'][getSpecies($pokemon)]['number'] >= 387 && $GLOBALS['gen'] < 4)
  141.         {
  142.                 $GLOBALS['gen'] = 4;
  143.         }
  144.         if ($GLOBALS['BattlePokemon'][getSpecies($pokemon)]['number'] >= 252 && $GLOBALS['gen'] < 4)
  145.         {
  146.                 $GLOBALS['gen'] = 3;
  147.         }
  148.         if ($GLOBALS['BattlePokemon'][getSpecies($pokemon)]['number'] >= 152 && $GLOBALS['gen'] < 4)
  149.         {
  150.                 $GLOBALS['gen'] = 2;
  151.         }
  152.        
  153.         return $pokemon;
  154. }
  155. function getSpecies($pokemon)
  156. {
  157.         global $currentpokemon;
  158.         if ($currentpokemon[$pokemon]) $pokemon = $currentpokemon[$pokemon];
  159.         if (substr($pokemon,0,4) === 'foe-') $pokemon = substr($pokemon,4);
  160.         if (substr($pokemon,0,5) === 'ally-') $pokemon = substr($pokemon,5);
  161.         $pos = strrpos($pokemon, '(');
  162.         if ($pos) $pokemon = substr($pokemon, $pos+1, -1);
  163.         if ($pokemon==='Ho-Oh') $pokemon = "Ho-oh";
  164.         return $pokemon;
  165. }
  166. function resolveMove($move)
  167. {
  168.         return str_replace(' ', '', $move);
  169. }
  170. function resolveUsername($move)
  171. {
  172.         return str_replace(' ', '', $move);
  173. }
  174. function resolveItem($move)
  175. {
  176.         return str_replace(' ', '', $move);
  177. }
  178. function resolveAbility($move)
  179. {
  180.         return str_replace(' ', '', $move);
  181. }
  182. function resolveStat($stat)
  183. {
  184.         $table = array(
  185.                 'attack' => 'atk',
  186.                 'defense' => 'def',
  187.                 'special attack' => 'spa',
  188.                 'special defense' => 'spd',
  189.                 'sp. att.' => 'spa',
  190.                 'sp. def.' => 'spd',
  191.                 'speed' => 'spe',
  192.         );
  193.         $stat = strtolower($stat);
  194.         if ($table[$stat]) return $table[$stat];
  195.         return $stat;
  196. }
  197. function isFoe($name)
  198. {
  199.         return resolveUsername($name) !== $GLOBALS['allyname'] && resolveUsername($name) !== uppercaseFirstLetter($GLOBALS['allyname']);
  200. }
  201. function markLastDamage($out)
  202. {
  203.         global $lastPokemon, $lastDamage;
  204.         $lastDamage[$lastPokemon] = count($out)-1;
  205. }
  206. function markLastAttack($out)
  207. {
  208.         global $lastPokemon, $lastAttack;
  209.         $lastAttack[$lastPokemon] = count($out)-1;
  210. }
  211. function attrLastAttack(&$out, $attr)
  212. {
  213.         global $lastPokemon, $lastAttack;
  214.         if ($lastAttack[$lastPokemon])
  215.         {
  216.                 $out[$lastAttack[$lastPokemon]] .= ' '.$attr;
  217.         }
  218. }
  219. function makeLastLethal(&$out)
  220. {
  221.         global $lastPokemon, $lastDamage;
  222.         if ($lastDamage[$lastPokemon] && !endsWith($out[$lastDamage[$lastPokemon]], ' (0.0)') && !endsWith($out[$lastDamage[$lastPokemon]], ' (0)'))
  223.         {
  224.                 $out[$lastDamage[$lastPokemon]] .= ' (lethal)';
  225.         }
  226. }
  227.  
  228. $logversion = '';
  229. function pokeConvert($text)
  230. {
  231.         global $convertNotDone, $logversion, $returnNow, $allpokemon, $out, $winner, $allyname, $playernames, $moveuser, $lastmove, $convertloopnum;
  232.         $english = false;
  233.         $GLOBALS['gen'] = 1;
  234.         $switchcounter = 0;
  235.         //echo "<div>started</div>";
  236.  
  237.         if (strpos($text, '<!DOCTYPE') === false && strpos($text, '<b><span style=\'color:') !== 0 && !startsWith($text, '<!--Log belonging to '))
  238.         {
  239.                 $convertNotDone = false;
  240.                 return array('error Replay file must an original Pokemon Online replay file. Copying and pasting replay text into another file will not work.');
  241.         }
  242.  
  243. //echo htmlspecialchars(var_export($text,true));
  244.  
  245. //              if (@$_REQUEST['dev']) echo '1: "'.$text.'"'."\n\n";
  246.  
  247. //$text = preg_replace('/\<!DOCTYPE html\>.*\<head\>/s', '<head>', $text);
  248. {
  249.         $headloc = strpos($text, '<head>');
  250.         if ($headloc) {
  251.                 $logversion = substr($text, 0, $headloc);
  252.                 if ($versionloc = strpos($logversion, '(version ')) {
  253.                         $logversion = substr($logversion, $versionloc+9);
  254.                         $logversion = substr($logversion, 0, strpos($logversion, ')'));
  255.                         //if (isset($_REQUEST['dev'])) var_dump($logversion);
  256.                 }
  257.                 $text = substr($text, $headloc);
  258.         }
  259. }
  260.  
  261. $text = preg_replace('/<head\>.*?\<\/head\>/s', '', $text);
  262. $text = preg_replace('/\<\/?(\!DOCTYPE|html|body|p)[^>]*\>/', '', $text);
  263. $text = preg_replace('/\<a[^>]*\>\<span[^>]*\>/', '', $text);
  264. $text = str_replace("</span></a>",'', $text);
  265. $text = str_replace("\n",'', $text);
  266. $text = str_replace("\r",'', $text);
  267. //var_export(htmlspecialchars($text));
  268.  
  269.  
  270. if (strpos($text, '.-->'))
  271. {
  272.         $text = str_replace("-->",'<br />-->', $text);
  273. }
  274.  
  275. $text = explode('<br />', $text);
  276.  
  277.         $allyname = '';
  278.  
  279.         $convertloopnum = 0;
  280.         do
  281.         {
  282.                 $convertNotDone = false;
  283.                 $returnNow = false;
  284.                 $out = pokeConvertInner($text);
  285.                 $convertloopnum++;
  286.         } while ($convertNotDone && $convertloopnum < 3);
  287.  
  288.         //echo var_export($allpokemon);
  289.         //echo "<div>$allyname</div>";
  290.  
  291.         if ($convertNotDone)
  292.         {
  293.                 return array('error This replay could not be processed.');
  294.         }
  295.         return $out;
  296. }
  297.  
  298. function pokeConvertInner($text)
  299. {
  300.         global $convertNotDone, $returnNow, $currentpokemon, $allpokemon, $out, $winner, $allyname, $playernames, $moveuser, $lastmove, $oldlines, $oldlinesoffset, $convertloopnum;
  301.         $allpokemon = array();
  302.        
  303.         $oldlines = array();
  304.         $oldlinesoffset = 0;
  305.  
  306.         $out = array();
  307.         $winner = false;
  308.         $moveuser = '';
  309.         $lastmove = '';
  310.         $currentpokemon = array();
  311.        
  312.         $firstline = true;
  313.        
  314.         foreach ($text as $i => $line)
  315.         {
  316.                 if ($firstline)
  317.                 {
  318.                         $firstline = false;
  319.                 }
  320.                 $line = str_replace('&', '&amp;', $line);
  321.                
  322.                 $line = preg_replace('/\<span class="[^>]*>/', '', $line, 1, $count);
  323.                 if ($count)
  324.                 {
  325.                         endsRemove($line, '</span>');
  326.                 }
  327.                
  328.                 $line = str_replace('</span>', '&gt;', $line);
  329.                 $line = preg_replace('/\<span[^>]*>/', '&lt;', $line);
  330.                 $line = str_replace('</div>', '', $line);
  331.                 $line = preg_replace('/\<div[^>]*>/', '', $line);
  332.                 $line = str_replace('</a>', '', $line);
  333.                 $line = preg_replace('/\<a[^>]*>/', '', $line);
  334.                 $line = str_replace('</b>', '&gt;', $line);
  335.                 $line = str_replace('<b>', '&lt;', $line);
  336.                 $line = trim($line);
  337.                 startsRemove($line, '-->');
  338.                 if (startsRemove($line, '<!--')) $line = '&lt;!&gt;'.$line;
  339.                 if (strpos($line, '<') !== false)
  340.                 {
  341.                         $convertNotDone = false;
  342.                         return array('error This does not appear to be a valid Pokemon Online replay (line '.($i+1).': '.($line).').');
  343.                 }
  344.                 $line = str_replace('&gt;', '>', $line);
  345.                 $line = str_replace('&lt;', '<', $line);
  346.                 $line = str_replace('>>', '>', $line);
  347.                 $line = str_replace('<<', '<', $line);
  348.                 $line = str_replace('&amp;', '&', $line);
  349.                 $line = trim($line);
  350.                 $newline = $line;
  351.                 $oldlines[] = array(count($out), $newline);
  352.                 if ($line === '')
  353.                 {
  354.                         $out[] = '';
  355.                 }
  356.                 else if (startsRemove($line, '<!>'))
  357.                 {
  358.                         $outcount = count($out);
  359.                         //$lastline = '';
  360.                         if ($outcount > 1) $lastline =& $out[$outcount-1];
  361.                         $statuses = array(
  362.                                 'fine' => 'none',
  363.                                 'koed' => 'fnt'
  364.                         );
  365.                         if (startsRemove($line, 'Log belonging to '))
  366.                         {
  367.                                 //$allyname = resolveUsername($line);
  368.                         }
  369.                         else if (preg_match('/^([^<>]+) sent out ([^<>]+)!( \([^<>]+\))?$/', $line, $matches))
  370.                         {
  371.                                 $pokemon = (isFoe($matches[1])?'foe-':'ally-').$matches[2].$matches[3];
  372.                                 namePokemon($pokemon);
  373.                                 $pokemon = str_replace(' ','',$pokemon);
  374.                                 if ($lastmove === 'Roar' || $lastmove === 'Whirlwind' || $lastmove === 'DragonTail' || $lastmove === 'CircleThrow')
  375.                                 {
  376.                                         $out[] = 'drag-out-anim switched-'.$pokemon;
  377.                                 }
  378.                                 else
  379.                                 {
  380.                                         $out[] = 'replace switched-'.$pokemon;
  381.                                 }
  382.                         }
  383.                         else if (preg_match('/^([^<>]+)\'s life: ([0-9]+)%.$/', $line, $matches))
  384.                         {
  385.                                 if (startsWith($lastline, 'switch-in ') || startsWith($lastline, 'replace '))
  386.                                 {
  387.                                         $lastline .= ' ('.$matches[2].')';
  388.                                 }
  389.                         }
  390.                         else if (preg_match('/^([^<>]+)\'s life: ([0-9]+)\/([0-9]+) HP.$/', $line, $matches))
  391.                         {
  392.                                 if (startsWith($lastline, 'switch-in ') || startsWith($lastline, 'replace '))
  393.                                 {
  394.                                         $lastline .= ' ('.number_format(100*intval($matches[2])/intval($matches[3]), 1, '.', '').')';
  395.                                 }
  396.                         }
  397.                         else if (preg_match('/^([^<>]+)\'s status: ([a-z]+).$/', $line, $matches))
  398.                         {
  399.                                 $status = $statuses[$matches[2]];
  400.                                 if ($status)
  401.                                 {
  402.                                         if (startsWith($lastline, 'switch-in ') || startsWith($lastline, 'replace '))
  403.                                         {
  404.                                                 if (endsWith($lastline,')'))
  405.                                                 {
  406.                                                         $lastline = substr($lastline,0,-1).'|'.$statuses[$matches[2]].')';
  407.                                                 }
  408.                                                 else $lastline = $lastline.' ('.$statuses[$matches[2]].')';
  409.                                         }
  410.                                 }
  411.                         }
  412.                         else if (preg_match('/^([^<>]+)\'s new HP is ([0-9]+)\/([0-9]+).$/', $line, $matches) ||
  413.                                  preg_match('/^([^<>]+)\'s new HP is ([0-9]+)%.$/', $line, $matches))
  414.                         {
  415.                                 if (!$matches[3]) $newhp = $matches[2];
  416.                                 else $newhp = number_format(100*intval($matches[2])/intval($matches[3]), 1, '.', '');
  417.                                 if ($GLOBALS['logversion'] !== '2.0' || $matches[3])
  418.                                 {
  419.                                         if (startsWith($lastline,'  r-recoil ') || startsWith($lastline,'  r-life-orb-recoil '))
  420.                                         {
  421.                                                 $lastline .= ' ('.$newhp.')';
  422.                                         }
  423.                                         else if (startsWith($lastline,'stealth-rock-damage '))
  424.                                         {
  425.                                                 $lastline .= ' ('.$newhp.')';
  426.                                         }
  427.                                         else if (startsWith($lastline,'  r-damage '))
  428.                                         {
  429.                                                 $lastline .= ' ('.$newhp.')';
  430.                                         }
  431.                                         else if (startsWith($lastline,'residual ') && (strpos($lastline, ' leech-seed ') || strpos($lastline, ' item-heal ') || strpos($lastline, ' wish ')))
  432.                                         {
  433.                                                 $lastline .= ' ('.$newhp.')';
  434.                                         }
  435.                                 }
  436.                         }
  437.                 }
  438.                 else if (startsRemove($line, '<Tier: >'))
  439.                 {
  440.                         $out[] = 'tier '.$line;
  441.                 }
  442.                 else if (startsRemove($line, '<Variation: >'))
  443.                 {
  444.                         $out[] = 'variation '.$line;
  445.                 }
  446.                 else if (startsRemove($line, '<Rule: >'))
  447.                 {
  448.                         $out[] = 'rule '.$line;
  449.                 }
  450.                 else if (startsRemove($line, '<Start of turn '))
  451.                 {
  452.                         endsRemove($line, '>');
  453.                         endsRemove($line, '!');
  454.                         $out[] = 'turn '.$line;
  455.                         if (substr($line, 0, -1) === '1' && $switchcounter < 100) $switchcounter += 100;
  456.                         else if ($switchcounter < 100) $switchcounter += 200;
  457.                         // damage doesn't actually happen here, but any undetected messages that do damage...
  458.                         markLastDamage($out);
  459.                 }
  460.                 else if (endsRemove($line, ' fainted!>'))
  461.                 {
  462.                         $out[] = 'faint '.resolvePokemon(substr($line, 1));
  463.                         makeLastLethal($out);
  464.                 }
  465.                 else if (endsRemove($line, ' is exerting its Pressure!'))
  466.                 {
  467.                         $out[] = '  r-pressure '.resolvePokemon($line);
  468.                 }
  469.                 else if (endsRemove($line, ' has Mold Breaker!'))
  470.                 {
  471.                         $out[] = '  r-mold-breaker '.resolvePokemon($line);
  472.                 }
  473.                 else if (endsRemove($line, ' is hit with recoil!'))
  474.                 {
  475.                         $out[] = '  r-recoil '.resolvePokemon($line).' ??';
  476.                         markLastDamage($out);
  477.                 }
  478.                 else if ($line === "<It's not very effective...>")
  479.                 {
  480.                         $out[] = '  r-resisted';
  481.                 }
  482.                 else if ($line === "But it failed!")
  483.                 {
  484.                         $out[] = '  r-failed '.$moveuser;
  485.                 }
  486.                 else if ($line === "But there was no target...")
  487.                 {
  488.                         $out[] = '  r-no-target '.$moveuser;
  489.                         attrLastAttack($out, 'no-target');
  490.                 }
  491.                 else if ($line === "It had no effect!")
  492.                 {
  493.                         $out[] = '  r-immune '.$movetarget;
  494.                 }
  495.                 else if ($line === "<But nothing happened!>")
  496.                 {
  497.                         $out[] = '  r-nothing-happened';
  498.                 }
  499.                 else if ($line === "<It's super effective!>")
  500.                 {
  501.                         $out[] = '  r-super-effective';
  502.                 }
  503.                 else if ($line === "<A critical hit!>")
  504.                 {
  505.                         $out[] = '  r-crit';
  506.                 }
  507.                 else if ($line === "<It hurt itself in its confusion!>")
  508.                 {
  509.                         $out[] = '  r-hurt-confusion';
  510.                 }
  511.                 else if ($line === "<It's a one hit KO!>")
  512.                 {
  513.                         $out[] = '  r-ohko';
  514.                 }
  515.                 else if ($line === "<The sunlight is strong!>")
  516.                 {
  517.                         $out[] = 'weather-upkeep sun';
  518.                 }
  519.                 else if ($line === "<Rain continues to fall!>")
  520.                 {
  521.                         $out[] = 'weather-upkeep rain';
  522.                 }
  523.                 else if ($line === "<The sunlight turned harsh!>")
  524.                 {
  525.                         $out[] = 'weather sun';
  526.                 }
  527.                 else if ($line === "<It started to rain!>")
  528.                 {
  529.                         $out[] = 'weather rain';
  530.                 }
  531.                 else if ($line === "<A hailstorm brewed!>")
  532.                 {
  533.                         $out[] = 'weather hail';
  534.                 }
  535.                 else if ($line === "<Hail continues to fall!>")
  536.                 {
  537.                         $out[] = 'weather hail';
  538.                 }
  539.                 else if ($line === "<A sandstorm brewed!>")
  540.                 {
  541.                         $out[] = 'weather sandstorm';
  542.                 }
  543.                 else if ($line === "<The sandstorm rages!>")
  544.                 {
  545.                         $out[] = 'weather-upkeep sandstorm';
  546.                 }
  547.                 else if ($line === "<The sunlight faded!>")
  548.                 {
  549.                         $out[] = 'weather none';
  550.                 }
  551.                 else if ($line === "<The rain stopped!>")
  552.                 {
  553.                         $out[] = 'weather none';
  554.                 }
  555.                 else if ($line === "<The sandstorm subsided!>")
  556.                 {
  557.                         $out[] = 'weather none';
  558.                 }
  559.                 else if ($line === "<The hail subsided!>")
  560.                 {
  561.                         $out[] = 'weather none';
  562.                 }
  563.                 else if ($line === '<All stat changes were eliminated!>')
  564.                 {
  565.                         $out[] = '  r-haze';
  566.                 }
  567.                 else if ($line === '<The battlers shared their pain!>')
  568.                 {
  569.                         $out[] = '  r-pain-split';
  570.                 }
  571.                 else if (endsRemove($line, '\'s Wonder Guard evades the attack!'))
  572.                 {
  573.                         $out[] = '  r-ability-evade '.resolvePokemon($line).' WonderGuard';
  574.                 }
  575.                 else if (endsRemove($line, ' avoided the attack!'))
  576.                 {
  577.                         attrLastAttack($out, 'miss');
  578.                         $out[] = '  r-avoid '.resolvePokemon($line).'';
  579.                 }
  580.                 else if (endsRemove($line, ' regained health!>'))
  581.                 {
  582.                         $out[] = '  r-heal '.resolvePokemon(substr($line, 1)).' ??';
  583.                 }
  584.                 else if (endsRemove($line, ' restored some HP!'))
  585.                 {
  586.                         $out[] = '  r-heal '.resolvePokemon($line).' ??';
  587.                 }
  588.                 else if (endsRemove($line, ' was poisoned!>'))
  589.                 {
  590.                         if ($lastmove === 'Toxic')
  591.                         {
  592.                                 $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' toxic';
  593.                         }
  594.                         else
  595.                         {
  596.                                 $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' psn';
  597.                         }
  598.                 }
  599.                 else if (endsRemove($line, ' was badly poisoned!>'))
  600.                 {
  601.                         $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' toxic';
  602.                 }
  603.                 else if (endsRemove($line, ' is already poisoned.>'))
  604.                 {
  605.                         $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' psn already';
  606.                 }
  607.                 else if (endsRemove($line, ' is already burnt.>'))
  608.                 {
  609.                         $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' brn already';
  610.                 }
  611.                 else if (endsRemove($line, ' is already paralyzed.>'))
  612.                 {
  613.                         $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' par already';
  614.                 }
  615.                 else if (endsRemove($line, ' calmed down!>'))
  616.                 {
  617.                         $out[] = '  r-calm '.resolvePokemon(substr($line, 1));
  618.                 }
  619.                 else if (endsRemove($line, ' is confused!>'))
  620.                 {
  621.                         $out[] = 'pre-move '.resolvePokemon(substr($line, 1)).' confused';
  622.                 }
  623.                 else if (endsRemove($line, ' is fast asleep!>'))
  624.                 {
  625.                         $out[] = 'pre-move '.resolvePokemon(substr($line, 1)).' slp';
  626.                 }
  627.                 else if (endsRemove($line, ' is being sent back!>'))
  628.                 {
  629.                         $out[] = 'pre-move '.resolvePokemon(substr($line, 1)).' switch-out';
  630.                 }
  631.                 else if (endsRemove($line, ' woke up!>'))
  632.                 {
  633.                         $out[] = '  r-cure-status '.resolvePokemon(substr($line, 1)).' slp';
  634.                 }
  635.                 else if (endsRemove($line, '\'s status cleared!'))
  636.                 {
  637.                         $out[] = '  r-cure '.resolvePokemon($line);
  638.                 }
  639.                 else if (endsRemove($line, '\'s status cleared!>'))
  640.                 {
  641.                         $out[] = '  r-cure '.resolvePokemon(substr($line, 1));
  642.                 }
  643.                 else if (endsRemove($line, ' landed on the ground!>'))
  644.                 {
  645.                         $out[] = '  r-turnstatus '.resolvePokemon(substr($line, 1)).' landed';
  646.                 }
  647.                 else if (endsRemove($line, ' protected itself!>'))
  648.                 {
  649.                         $out[] = '  r-turnstatus '.resolvePokemon(substr($line, 1)).' protect';
  650.                 }
  651.                 else if (endsRemove($line, ' shrouded itself with Magic Coat!>'))
  652.                 {
  653.                         $out[] = '  r-turnstatus '.resolvePokemon(substr($line, 1)).' magic-coat';
  654.                 }
  655.                 else if (endsRemove($line, ' braced itself!>'))
  656.                 {
  657.                         $out[] = '  r-turnstatus '.resolvePokemon(substr($line, 1)).' endure';
  658.                 }
  659.                 else if (endsRemove($line, ' is tightening its focus!>'))
  660.                 {
  661.                         $out[] = '  r-turnstatus '.resolvePokemon(substr($line, 1)).' focusing';
  662.                 }
  663.                 else if (endsRemove($line, ' is hurt by poison!>'))
  664.                 {
  665.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' poison ??';
  666.                         markLastDamage($out);
  667.                 }
  668.                 else if (endsRemove($line, ' is hurt by its burn!>'))
  669.                 {
  670.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' burn ??';
  671.                         markLastDamage($out);
  672.                 }
  673.                 else if (endsRemove($line, ' was burned!>'))
  674.                 {
  675.                         $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' brn';
  676.                 }
  677.                 else if (endsRemove($line, ' is paralyzed! It may be unable to move!>'))
  678.                 {
  679.                         $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' par';
  680.                 }
  681.                 else if (endsRemove($line, ' is paralyzed! It can\'t move!>'))
  682.                 {
  683.                         $out[] = 'cant-move '.resolvePokemon(substr($line, 1)).' fully-paralyzed';
  684.                 }
  685.                 else if (endsRemove($line, ' can\'t attack while in the air!>'))
  686.                 {
  687.                         $out[] = 'cant-move '.resolvePokemon(substr($line, 1)).' in-air';
  688.                 }
  689.                 else if (endsRemove($line, ' became confused!>'))
  690.                 {
  691.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' confused';
  692.                 }
  693.                 else if (endsRemove($line, ' snapped out its confusion!>'))
  694.                 {
  695.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' confused end';
  696.                 }
  697.                 else if (endsRemove($line, " was prevented from healing!>"))
  698.                 {
  699.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' healblock';
  700.                 }
  701.                 else if (endsRemove($line, " must recharge!>"))
  702.                 {
  703.                         $out[] = 'cant-move '.resolvePokemon(substr($line, 1)).' must-recharge';
  704.                 }
  705.                 else if (endsRemove($line, " vanished instantly!>"))
  706.                 {
  707.                         $out[] = 'prepare-move '.resolvePokemon(substr($line, 1)).' ShadowForce';
  708.                 }
  709.                 else if (endsRemove($line, " sprang up!>"))
  710.                 {
  711.                         $out[] = 'prepare-move '.resolvePokemon(substr($line, 1)).' Bounce';
  712.                 }
  713.                 else if (endsRemove($line, " burrowed its way under the ground!>"))
  714.                 {
  715.                         $out[] = 'prepare-move '.resolvePokemon(substr($line, 1)).' Dig';
  716.                 }
  717.                 else if (endsRemove($line, " hid underwater!>"))
  718.                 {
  719.                         $out[] = 'prepare-move '.resolvePokemon(substr($line, 1)).' Dive';
  720.                 }
  721.                 else if (endsRemove($line, " flew high up!>"))
  722.                 {
  723.                         $out[] = 'prepare-move '.resolvePokemon(substr($line, 1)).' Fly';
  724.                 }
  725.                 else if (endsRemove($line, " absorbed light!>"))
  726.                 {
  727.                         $out[] = 'prepare-move '.resolvePokemon(substr($line, 1)).' SolarBeam';
  728.                 }
  729.                 else if (endsRemove($line, " became cloaked in a harsh light!>"))
  730.                 {
  731.                         $out[] = 'prepare-move '.resolvePokemon(substr($line, 1)).' SkyAttack';
  732.                 }
  733.                 else if (endsRemove($line, "'s heal block wore off!>"))
  734.                 {
  735.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' healblock end';
  736.                 }
  737.                 else if (endsRemove($line, ' fell asleep!>'))
  738.                 {
  739.                         $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' slp';
  740.                 }
  741.                 else if (endsRemove($line, ' woke up!'))
  742.                 {
  743.                         $out[] = '  r-cure-status '.resolvePokemon($line).' slp';
  744.                 }
  745.                 else if (endsRemove($line, ' was frozen solid!>'))
  746.                 {
  747.                         $out[] = '  r-status '.resolvePokemon(substr($line, 1)).' frz';
  748.                 }
  749.                 else if (endsRemove($line, ' thawed out!>'))
  750.                 {
  751.                         $out[] = '  r-cure-status '.resolvePokemon(substr($line, 1)).' frz';
  752.                 }
  753.                 else if (endsRemove($line, ' is frozen solid!>'))
  754.                 {
  755.                         $out[] = 'cant-move '.resolvePokemon(substr($line, 1)).' frozen';
  756.                 }
  757.                 else if (endsRemove($line, ' cut its own HP and maximized its Attack!>'))
  758.                 {
  759.                         $out[] = '  r-belly-drum '.resolvePokemon(substr($line, 1)).'';
  760.                 }
  761.                 else if (endsRemove($line, ' flinched!'))
  762.                 {
  763.                         $out[] = 'flinch '.resolvePokemon($line);
  764.                 }
  765.                 else if (endsRemove($line, ' is hurt by its Life Orb!'))
  766.                 {
  767.                         $out[] = '  r-life-orb-recoil '.resolvePokemon($line).' ??';
  768.                         markLastDamage($out);
  769.                 }
  770.                 else if (endsRemove($line, ' is floating on a balloon!>'))
  771.                 {
  772.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' balloon';
  773.                 }
  774.                 else if (endsRemove($line, ' is floating on a balloon!'))
  775.                 {
  776.                         $out[] = '  r-volatile '.resolvePokemon($line).' balloon';
  777.                 }
  778.                 else if (endsRemove($line, "'s Air Balloon popped!>") || endsRemove($line, "'s Balloon popped!>"))
  779.                 {
  780.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' balloon end';
  781.                 }
  782.                 else if (endsRemove($line, "'s Air Balloon popped!") || endsRemove($line, "'s Balloon popped!"))
  783.                 {
  784.                         $out[] = '  r-volatile '.resolvePokemon($line).' balloon end';
  785.                 }
  786.                 else if (endsRemove($line, "'s Rain Dish heals it!>"))
  787.                 {
  788.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' ability-heal RainDish';
  789.                 }
  790.                 else if (endsRemove($line, "'s Ice Body heals it!>"))
  791.                 {
  792.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' ability-heal IceBody';
  793.                 }
  794.                 else if (endsRemove($line, " was seeded!>"))
  795.                 {
  796.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' seed';
  797.                 }
  798.                 else if (endsRemove($line, "'s Drought intensified the sun's rays!>"))
  799.                 {
  800.                         $out[] = '  r-weather '.resolvePokemon(substr($line, 1)).' sun';
  801.                 }
  802.                 else if (endsRemove($line, "'s Sand Stream whipped up a sandstorm!>"))
  803.                 {
  804.                         $out[] = '  r-weather '.resolvePokemon(substr($line, 1)).' sandstorm';
  805.                 }
  806.                 else if (endsRemove($line, " is buffeted by the sandstorm!>"))
  807.                 {
  808.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' sandstorm ??';
  809.                         markLastDamage($out);
  810.                 }
  811.                 else if (endsRemove($line, "'s Snow Warning whipped up a hailstorm!>"))
  812.                 {
  813.                         $out[] = '  r-weather '.resolvePokemon(substr($line, 1)).' hail';
  814.                 }
  815.                 else if (endsRemove($line, " is buffeted by the hail!>"))
  816.                 {
  817.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' hail ??';
  818.                         markLastDamage($out);
  819.                 }
  820.                 else if (endsRemove($line, "'s Drizzle made it rain!>"))
  821.                 {
  822.                         $out[] = '  r-weather '.resolvePokemon(substr($line, 1)).' rain';
  823.                 }
  824.                 else if (endsRemove($line, " twisted the dimensions!>"))
  825.                 {
  826.                         $out[] = '  r-pseudo-weather '.resolvePokemon(substr($line, 1)).' TrickRoom';
  827.                 }
  828.                 else if ($line === '<The twisted dimensions returned to normal!>')
  829.                 {
  830.                         $out[] = 'pseudo-weather-end TrickRoom';
  831.                 }
  832.                 else if (endsRemove($line, " swapped the Sp. Def. and the Defense of all the pokemon!>"))
  833.                 {
  834.                         $out[] = '  r-pseudo-weather '.resolvePokemon(substr($line, 1)).' WonderRoom';
  835.                 }
  836.                 else if ($line === '<The Sp. Def and Defense of the pokemon went back to normal!>')
  837.                 {
  838.                         $out[] = 'pseudo-weather-end WonderRoom';
  839.                 }
  840.                 else if (endsRemove($line, " cancelled the items' effects!>"))
  841.                 {
  842.                         $out[] = '  r-pseudo-weather '.resolvePokemon(substr($line, 1)).' MagicRoom';
  843.                 }
  844.                 else if ($line === '<The items are now working again!>')
  845.                 {
  846.                         $out[] = 'pseudo-weather-end MagicRoom';
  847.                 }
  848.                 else if (endsRemove($line, " is already preparing its next move!"))
  849.                 {
  850.                         $out[] = '  r-custap '.resolvePokemon($line);
  851.                 }
  852.                 else if (startsRemove($line, "<It doesn't affect "))
  853.                 {
  854.                         $out[] = '  r-doesnt-affect '.resolvePokemon(substr($line, 0, -4));
  855.                 }
  856.                 else if (endsRemove($line, "mon hearing the song will faint in three turns!>"))
  857.                 {
  858.                         $out[] = '  r-perish-song '.$moveuser;
  859.                 }
  860.                 else if (endsRemove($line, "'s health is sapped by leech seed.>"))
  861.                 {
  862.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' leech-seed ?? ??';
  863.                         markLastDamage($out);
  864.                 }
  865.                 else if (endsRemove($line, " has Teravolt!"))
  866.                 {
  867.                         $out[] = '  r-ability-notify '.resolvePokemon($line).' Teravolt';
  868.                 }
  869.                 else if (endsRemove($line, " has Cloud Nine!"))
  870.                 {
  871.                         $out[] = '  r-ability-notify '.resolvePokemon($line).' CloudNine';
  872.                 }
  873.                 else if (endsRemove($line, " has Air Lock!"))
  874.                 {
  875.                         $out[] = '  r-ability-notify '.resolvePokemon($line).' AirLock';
  876.                 }
  877.                 else if (endsRemove($line, " has Turboblaze!") || endsRemove($line, " has Turbo Blaze!"))
  878.                 {
  879.                         $out[] = '  r-ability-notify '.resolvePokemon($line).' Turboblaze';
  880.                 }
  881.                 else if (endsRemove($line, " has Turboblaze!") || endsRemove($line, " has TeraVoltage!"))
  882.                 {
  883.                         $out[] = '  r-ability-notify '.resolvePokemon($line).' Teravolt';
  884.                 }
  885.                 else if (endsRemove($line, "'s Speed Boost increases its speed!"))
  886.                 {
  887.                         $out[] = 'residual '.resolvePokemon($line).' ability-activate SpeedBoost';
  888.                 }
  889.                 else if (endsRemove($line, "'s Poison Point activates!>"))
  890.                 {
  891.                         $out[] = 'residual '.resolvePokemon(substr($line,1)).' ability-activate PoisonPoint';
  892.                 }
  893.                 else if (endsRemove($line, "'s Download activates!"))
  894.                 {
  895.                         $out[] = 'residual '.resolvePokemon($line).' ability-activate Download';
  896.                 }
  897.                 else if (endsRemove($line, "'s Cursed Body activates!"))
  898.                 {
  899.                         $out[] = 'residual '.resolvePokemon($line).' ability-activate CursedBody';
  900.                 }
  901.                 else if (endsRemove($line, "'s Flame Body activates!>"))
  902.                 {
  903.                         $out[] = 'residual '.resolvePokemon(substr($line,1)).' ability-activate FlameBody';
  904.                 }
  905.                 else if (endsRemove($line, "'s stat changes were eliminated!>"))
  906.                 {
  907.                         $out[] = '  r-poke-haze '.resolvePokemon(substr($line,1)).'';
  908.                 }
  909.                 else if (endsRemove($line, "'s Quick Claw activated!"))
  910.                 {
  911.                         $out[] = 'residual '.resolvePokemon($line).' item-activate QuickClaw';
  912.                         $lastmove = 'Toxic';
  913.                 }
  914.                 else if (endsRemove($line, "'s Toxic Orb activated!"))
  915.                 {
  916.                         $out[] = 'residual '.resolvePokemon($line).' item-activate ToxicOrb';
  917.                         $lastmove = 'Toxic';
  918.                 }
  919.                 else if (endsRemove($line, "'s Flame Orb activated!"))
  920.                 {
  921.                         $out[] = 'residual '.resolvePokemon($line).' item-activate FlameOrb';
  922.                 }
  923.                 else if (endsRemove($line, ' was dragged out!>'))
  924.                 {
  925.                         $prevline = count($out)-1;
  926.                         if ($out[$prevline] === 'faint '.resolvePokemon(substr($line, 1)))
  927.                         {
  928.                                 $out[$prevline] = 'drag-out '.resolvePokemon(substr($line, 1));
  929.                                 $out[] = 'faint '.resolvePokemon(substr($line, 1));
  930.                         }
  931.                         else
  932.                         {
  933.                                 $out[] = 'drag-out '.resolvePokemon(substr($line, 1));
  934.                         }
  935.                 }
  936.                 else if (endsRemove($line, ' made a substitute!>'))
  937.                 {
  938.                         $out[] = '  r-sub '.resolvePokemon(substr($line, 1));
  939.                 }
  940.                 else if (endsRemove($line, ' already has a substitute.>'))
  941.                 {
  942.                         $out[] = '  r-sub '.resolvePokemon(substr($line, 1)).' already';
  943.                 }
  944.                 else if (endsRemove($line, ' is already confused.>'))
  945.                 {
  946.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' confused already';
  947.                 }
  948.                 else if (endsRemove($line, ' hung on using its Focus Sash!') || endsRemove($line, ' hung on using its focus sash!'))
  949.                 {
  950.                         $out[] = '  r-sash '.resolvePokemon($line);
  951.                 }
  952.                 else if (endsRemove($line, ' held on thanks to Sturdy!'))
  953.                 {
  954.                         $out[] = '  r-sturdy '.resolvePokemon($line);
  955.                         $GLOBALS['gen'] = 5;
  956.                 }
  957.                 else if (endsRemove($line, ' regains health with its Regenerator!') || endsRemove($line, ' regains health with its Regeneration!'))
  958.                 {
  959.                         // ignore
  960.                 }
  961.                 else if (endsRemove($line, ' is watching the battle.>'))
  962.                 {
  963.                         $out[] = 'spectator '.substr($line, 1);
  964.                 }
  965.                 else if (endsRemove($line, ' stopped watching the battle.>'))
  966.                 {
  967.                         $out[] = 'spectator-end '.substr($line, 1);
  968.                 }
  969.                 else if (endsRemove($line, ' had its energy drained!'))
  970.                 {
  971.                         $out[] = '  r-drain '.resolvePokemon($line).' ?? ??';
  972.                 }
  973.                 else if (endsRemove($line, ' went to sleep and became healthy!>'))
  974.                 {
  975.                         $out[] = '  r-rested '.resolvePokemon(substr($line,1)).'';
  976.                 }
  977.                 else if (startsRemove($line, '<Pointed stones dug into '))
  978.                 {
  979.                         $pokemon = resolvePokemon(substr($line, 0, -2));
  980.                         $damage = 12.5 * getDamageTaken('Rock', $GLOBALS['BattlePokemon'][getSpecies($pokemon)]);
  981.                         //echo '['.$pokemon.'|'.getSpecies($pokemon).']';
  982.                         $out[] = 'stealth-rock-damage '.$pokemon.' '.$damage;
  983.                         markLastDamage($out);
  984.                 }
  985.                 else if (endsRemove($line, "'s wish came true!>"))
  986.                 {
  987.                         $out[] = 'residual ?? wish '.resolveUsername(substr($line, 1)).' ??';
  988.                 }
  989.                 else if ($line === "<The healing wish came true!>")
  990.                 {
  991.                         $out[] = 'residual ?? healing-wish ?? ??';
  992.                 }
  993.                 else if ($line === "<A soothing aroma wafted through the area!>")
  994.                 {
  995.                         $out[] = '  r-cure-all '.$moveuser.' Aromatherapy';
  996.                 }
  997.                 else if ($line === "<A bell chimed!>")
  998.                 {
  999.                         $out[] = '  r-cure-all '.$moveuser.' HealBell';
  1000.                 }
  1001.                 else if (endsRemove($line, " has bad dreams!>"))
  1002.                 {
  1003.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' bad-dreams ??';
  1004.                         markLastDamage($out);
  1005.                 }
  1006.                 else if (endsRemove($line, " took the Doom Desire attack!>"))
  1007.                 {
  1008.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' move DoomDesire';
  1009.                 }
  1010.                 else if (endsRemove($line, " chose Doom Desire as its destiny!>"))
  1011.                 {
  1012.                         $out[] = '  r-doom-desire '.resolvePokemon(substr($line, 1));
  1013.                 }
  1014.                 else if (endsRemove($line, ' is hurt by spikes!>'))
  1015.                 {
  1016.                         $out[] = 'spikes-damage '.resolvePokemon(substr($line, 1)).' ??';
  1017.                         markLastDamage($out);
  1018.                 }
  1019.                 else if (endsRemove($line, ' blew away Leech Seed!>'))
  1020.                 {
  1021.                         $out[] = '  r-blow-away '.resolvePokemon(substr($line, 1)).' LeechSeed';
  1022.                 }
  1023.                 else if (endsRemove($line, ' blew away Stealth Rock!>'))
  1024.                 {
  1025.                         $out[] = '  r-blow-away '.resolvePokemon(substr($line, 1)).' StealthRock';
  1026.                 }
  1027.                 else if (endsRemove($line, ' blew away Spikes!>'))
  1028.                 {
  1029.                         $out[] = '  r-blow-away '.resolvePokemon(substr($line, 1)).' Spikes';
  1030.                 }
  1031.                 else if (endsRemove($line, ' blew away Toxic Spikes!>'))
  1032.                 {
  1033.                         $out[] = '  r-blow-away '.resolvePokemon(substr($line, 1)).' ToxicSpikes';
  1034.                 }
  1035.                 else if (endsRemove($line, ' fell for the taunt!>'))
  1036.                 {
  1037.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' taunt';
  1038.                 }
  1039.                 else if (endsRemove($line, '\'s Flash Fire raised the power of its Fire-type moves!>'))
  1040.                 {
  1041.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' flash-fire';
  1042.                 }
  1043.                 else if (endsRemove($line, ' is now tormented!>'))
  1044.                 {
  1045.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' torment';
  1046.                 }
  1047.                 else if (endsRemove($line, ' received an encore!>'))
  1048.                 {
  1049.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' encore';
  1050.                 }
  1051.                 else if (endsRemove($line, "'s taunt ended!>"))
  1052.                 {
  1053.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' taunt end';
  1054.                 }
  1055.                 else if (endsRemove($line, "'s Encore ended!>"))
  1056.                 {
  1057.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' encore end';
  1058.                 }
  1059.                 else if (endsRemove($line, "'s substitute faded!>"))
  1060.                 {
  1061.                         $out[] = '  r-sub-fade '.resolvePokemon(substr($line, 1));
  1062.                 }
  1063.                 else if (endsRemove($line, "'s substitute took the damage!>"))
  1064.                 {
  1065.                         $out[] = '  r-sub-damage '.resolvePokemon(substr($line, 1));
  1066.                 }
  1067.                 else if (endsRemove($line, " planted its roots!>"))
  1068.                 {
  1069.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' ingrain';
  1070.                 }
  1071.                 else if (endsRemove($line, " surrounded itself with a veil of water!>"))
  1072.                 {
  1073.                         $out[] = '  r-volatile '.resolvePokemon(substr($line, 1)).' aqua-ring';
  1074.                 }
  1075.                 else if (endsRemove($line, " absorbed nutrients with its roots!>"))
  1076.                 {
  1077.                         $out[] = 'residual '.resolvePokemon(substr($line, 1)).' heal ingrain';
  1078.                 }
  1079.                 else if (startsRemove($line, "<Aquaring restored "))
  1080.                 {
  1081.                         endsRemove($line, "'s HP.>");
  1082.                         $out[] = 'residual '.resolvePokemon($line).' heal aqua-ring';
  1083.                 }
  1084.                 else if (endsRemove($line, " is trying to take its foe with it!>"))
  1085.                 {
  1086.                         $out[] = '  r-destiny-bond '.resolvePokemon(substr($line, 1));
  1087.                 }
  1088.                 else if (preg_match('/^\<([^<>]+) can\'t use ([^<>]+) after the taunt!\>$/', $line, $matches))
  1089.                 {
  1090.                         $out[] = 'cant-move '.resolvePokemon($matches[1]).' taunt '.resolveMove($matches[2]);
  1091.                 }
  1092.                 else if (preg_match('/^([^<>]+) used \<([^<>]+)\>!$/', $line, $matches))
  1093.                 {
  1094.                         $moveuser = resolvePokemon($matches[1]);
  1095.                         $movetarget = 'foeof-'.resolvePokemon($matches[1]);
  1096.                         $lastmove = resolveMove($matches[2]);
  1097.                         $out[] = 'move '.$moveuser.' '.resolveMove($matches[2]).' ??';
  1098.                         markLastAttack($out);
  1099.                        
  1100.                         if ($matches[2] === 'Explosion' || $matches[2] === 'Selfdestruct' || $matches[2] === 'Lunar Dance' || $matches[2] === 'Healing Wish' || $matches[2] === 'Memento' || $matches[2] === 'Final Gambit')
  1101.                         {
  1102.                                 markLastDamage($out);
  1103.                         }
  1104.                 }
  1105.                 else if (preg_match('/^([^<>]+) sent out ([^<>]+)!( \([^<>]+\))?$/', $line, $matches))
  1106.                 {
  1107.                         if ($allpokemon[$matches[2]] && $allpokemon[$matches[2]] != resolveUsername($matches[1]))
  1108.                         {
  1109.                                 $allpokemon[$matches[2]] = false;
  1110.                         }
  1111.                         else if ($allpokemon[$matches[2]] !== false)
  1112.                         {
  1113.                                 $allpokemon[$matches[2]] = resolveUsername($matches[1]);
  1114.                         }
  1115.                         $pokemon = (isFoe($matches[1])?'foe-':'ally-').$matches[2].$matches[3];
  1116.                         namePokemon($pokemon);
  1117.                         $pokemon = str_replace(' ','',$pokemon);
  1118.                         $out[] = 'switch-in switched-'.$pokemon;
  1119.                         $lastmove = 'switch';
  1120.                        
  1121.                         if ($switchcounter < 99) $switchcounter++;
  1122.                 }
  1123.                 else if (preg_match('/^\<Pointed stones float in the air around ([^<>]+)\'s team!\>?$/', $line, $matches))
  1124.                 {
  1125.                         $side = (isFoe($matches[1])?'foe':'ally');
  1126.                         $out[] = '  r-side-condition '.$side.' StealthRock';
  1127.                 }
  1128.                 else if (preg_match('/^\<Spikes were scattered all around the feet of ([^<>]+)\'s team!\>?$/', $line, $matches))
  1129.                 {
  1130.                         $side = (isFoe($matches[1])?'foe':'ally');
  1131.                         $out[] = '  r-side-condition '.$side.' Spikes';
  1132.                 }
  1133.                 else if (preg_match('/^\<Poison spikes were scattered all around the feet of ([^<>]+)\'s team!\>?$/', $line, $matches))
  1134.                 {
  1135.                         $side = (isFoe($matches[1])?'foe':'ally');
  1136.                         $out[] = '  r-side-condition '.$side.' ToxicSpikes';
  1137.                 }
  1138.                 else if (preg_match('/^\<A tailwind started blowing behind ([^<>]+)\'s team!\>?$/', $line, $matches))
  1139.                 {
  1140.                         $side = (isFoe($matches[1])?'foe':'ally');
  1141.                         $out[] = '  r-side-condition '.$side.' Tailwind';
  1142.                 }
  1143.                 else if (preg_match('/^\<([^<>]+)\'s team tailwind petered out!\>?$/', $line, $matches))
  1144.                 {
  1145.                         $side = (isFoe($matches[1])?'foe':'ally');
  1146.                         $out[] = 'side-condition '.$side.' Tailwind end';
  1147.                 }
  1148.                 else if (preg_match('/^\<Reflect raised ([^<>]+)\'s team defense!\>?$/', $line, $matches))
  1149.                 {
  1150.                         $side = (isFoe($matches[1])?'foe':'ally');
  1151.                         $out[] = '  r-side-condition '.$side.' Reflect';
  1152.                 }
  1153.                 else if (preg_match('/^\<([^<>]+)\'s reflect wore off!\>?$/', $line, $matches))
  1154.                 {
  1155.                         $side = (isFoe($matches[1])?'foe':'ally');
  1156.                         $out[] = '  r-side-condition '.$side.' Reflect end';
  1157.                 }
  1158.                 else if (preg_match('/^\<([^<>]+)\'s team became cloaked in a mystical veil!\>?$/', $line, $matches))
  1159.                 {
  1160.                         $side = (isFoe($matches[1])?'foe':'ally');
  1161.                         $out[] = '  r-side-condition '.$side.' Safeguard';
  1162.                 }
  1163.                 else if (preg_match('/^\<([^<>]+)\'s team is no longer protected by Safeguard!\>?$/', $line, $matches))
  1164.                 {
  1165.                         $side = (isFoe($matches[1])?'foe':'ally');
  1166.                         $out[] = '  r-side-condition '.$side.' Safeguard end';
  1167.                 }
  1168.                 else if (preg_match('/^\<Light Screen raised ([^<>]+)\'s team special defense!\>?$/', $line, $matches))
  1169.                 {
  1170.                         $side = (isFoe($matches[1])?'foe':'ally');
  1171.                         $out[] = '  r-side-condition '.$side.' LightScreen';
  1172.                 }
  1173.                 else if (preg_match('/^\<([^<>]+)\'s light screen wore off!\>?$/', $line, $matches))
  1174.                 {
  1175.                         $side = (isFoe($matches[1])?'foe':'ally');
  1176.                         $out[] = '  r-side-condition '.$side.' LightScreen end';
  1177.                 }
  1178.                 else if (preg_match('/^\<([^<>]+) shattered ([^<>]+)\'s team protections!\>?$/', $line, $matches))
  1179.                 {
  1180.                         $side = (isFoe($matches[2])?'foe':'ally');
  1181.                         $out[] = '  r-shatter '.resolvePokemon($matches[1]).' '.$side;
  1182.                 }
  1183.                 else if (preg_match('/^([^<>]+)\'s Synchronize changes the status of ([^<>]+)!$/', $line, $matches))
  1184.                 {
  1185.                         $out[] = 'residual '.resolvePokemon($matches[1]).' ability-activate Synchronize '.resolvePokemon($matches[2]).'';
  1186.                 }
  1187.                 else if (preg_match('/^([^<>]+) called ([^<>]+) back!$/', $line, $matches))
  1188.                 {
  1189.                         $pokemon = (isFoe($matches[1])?'foe-':'ally-').$matches[2];
  1190.                         $pokemon = str_replace(' ','',$pokemon);
  1191.                         $out[] = 'switch-out '.$pokemon;
  1192.                 }
  1193.                 else if (preg_match('/^\<?([^<>]+) transformed into ([^<>]+)!\>?$/', $line, $matches))
  1194.                 {
  1195.                         $out[] = '  r-transform '.resolvePokemon($matches[1]).' '.resolveUsername($matches[2]).'';
  1196.                 }
  1197.                 else if (preg_match('/^\<([^<>]+) made ([^<>]+) feel drowsy!\>$/', $line, $matches))
  1198.                 {
  1199.                         $out[] = '  r-volatile '.resolvePokemon($matches[2]).' drowsy start '.resolvePokemon($matches[1]).'';
  1200.                 }
  1201.                 else if (preg_match('/^([^<>]+) is hurt by ([^<>]+)\'s ([A-Za-z .\']+)!$/', $line, $matches))
  1202.                 {
  1203.                         $out[] = '  r-foe-item-damage '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]).' '.resolveItem($matches[3]).' ??';
  1204.                         resolvePokemon($matches[1]); // is the one taking the damage
  1205.                         markLastDamage($out);
  1206.                 }
  1207.                 else if (preg_match('/^\<([^<>]+) was hurt by ([A-Za-z .\']+)!\>$/', $line, $matches))
  1208.                 {
  1209.                         $out[] = 'residual '.resolvePokemon($matches[1]).' move-damage '.resolveItem($matches[2]).' ??';
  1210.                         markLastDamage($out);
  1211.                 }
  1212.                 else if (preg_match('/^([^<>]+) is hurt by its ([A-Za-z .\']+)!$/', $line, $matches))
  1213.                 {
  1214.                         $out[] = 'residual '.resolvePokemon($matches[1]).' item-damage '.resolveItem($matches[2]).' ??';
  1215.                         markLastDamage($out);
  1216.                 }
  1217.                 else if (preg_match('/^([^<>]+) was hurt by Black Sludge!$/', $line, $matches))
  1218.                 {
  1219.                         $out[] = 'residual '.resolvePokemon($matches[1]).' item-damage BlackSludge ??';
  1220.                         markLastDamage($out);
  1221.                 }
  1222.                 else if (preg_match('/^([^<>]+) restored its stats using ([A-Za-z .\']+)!$/', $line, $matches))
  1223.                 {
  1224.                         $out[] = 'residual '.resolvePokemon($matches[1]).' item-restore '.resolveItem($matches[2]);
  1225.                 }
  1226.                 else if (preg_match('/^([^<>]+) restored a little HP using its ([A-Za-z .\']+)!$/', $line, $matches))
  1227.                 {
  1228.                         $out[] = 'residual '.resolvePokemon($matches[1]).' item-heal '.resolveItem($matches[2]);
  1229.                 }
  1230.                 else if (preg_match('/^\<([^<>]+) restored HP using its ([A-Za-z .\']+)!\>$/', $line, $matches))
  1231.                 {
  1232.                         $out[] = 'residual '.resolvePokemon($matches[1]).' ability-heal '.resolveAbility($matches[2]);
  1233.                 }
  1234.                 else if (preg_match('/^([^<>]+) used its Mental Herb to come back to (his|her|its) senses!$/', $line, $matches))
  1235.                 {
  1236.                         $out[] = 'residual '.resolvePokemon($matches[1]).' item-customcure MentalHerb';
  1237.                 }
  1238.                 else if (preg_match('/^\<([^<>]+)\'s Hydration heals its status!\>$/', $line, $matches))
  1239.                 {
  1240.                         $out[] = 'residual '.resolvePokemon($matches[1]).' ability-cure Hydration';
  1241.                 }
  1242.                 else if (preg_match('/^\<([^<>]+)\'s Insomnia cures it!\>$/', $line, $matches))
  1243.                 {
  1244.                         $out[] = 'residual '.resolvePokemon($matches[1]).' ability-cure Insomnia';
  1245.                 }
  1246.                 else if (preg_match('/^\<([^<>]+)\'s Shed Skin heals its status!\>$/', $line, $matches))
  1247.                 {
  1248.                         $out[] = 'residual '.resolvePokemon($matches[1]).' ability-cure ShedSkin';
  1249.                 }
  1250.                 else if (preg_match('/^The attack of ([^<>]+) missed!$/', $line, $matches))
  1251.                 {
  1252.                         $out[] = '  r-miss '.resolvePokemon($matches[1]);
  1253.                         attrLastAttack($out, 'miss');
  1254.                 }
  1255.                 else if (preg_match('/^([^<>]+)\'s ([a-zA-Z .]+) drastically fell!$/', $line, $matches))
  1256.                 {
  1257.                         $out[] = '  r-unboost '.resolvePokemon($matches[1]).' '.resolveStat($matches[2]).' 3';
  1258.                 }
  1259.                 else if (preg_match('/^([^<>]+)\'s ([a-zA-Z .]+) sharply fell!$/', $line, $matches))
  1260.                 {
  1261.                         $out[] = '  r-unboost '.resolvePokemon($matches[1]).' '.resolveStat($matches[2]).' 2';
  1262.                 }
  1263.                 else if (preg_match('/^([^<>]+)\'s ([a-zA-Z .]+) fell!$/', $line, $matches))
  1264.                 {
  1265.                         $out[] = '  r-unboost '.resolvePokemon($matches[1]).' '.resolveStat($matches[2]).' 1';
  1266.                 }
  1267.                 else if (preg_match('/^([^<>]+) lost ([0-9]+)% of its health!$/', $line, $matches))
  1268.                 {
  1269.                         $out[] = '  r-damage '.resolvePokemon($matches[1]).' '.$matches[2];
  1270.                         markLastDamage($out);
  1271.                 }
  1272.                 else if (preg_match('/^([^<>]+) lost ([0-9]+) HP! \(([0-9]+)% of its health\)$/', $line, $matches))
  1273.                 {
  1274.                         $out[] = '  r-damage '.resolvePokemon($matches[1]).' '.$matches[3];
  1275.                         markLastDamage($out);
  1276.                 }
  1277.                 else if (preg_match('/^([^<>]+) traced ([^<>]+)\'s ([A-Za-z ]+)!$/', $line, $matches))
  1278.                 {
  1279.                         $out[] = '  r-trace '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]).' '.resolveAbility($matches[3]);
  1280.                 }
  1281.                 else if (preg_match('/^\<([^<>]+) knocked off ([^<>]+)\'s ([A-Za-z ]+)!\>$/', $line, $matches))
  1282.                 {
  1283.                         $out[] = '  r-knock-off '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]).' '.resolveAbility($matches[3]);
  1284.                 }
  1285.                 else if (preg_match('/^\<([^<>]+) knocked ([^<>]+) on the ground!\>$/', $line, $matches))
  1286.                 {
  1287.                         $out[] = '  r-volatile '.resolvePokemon($matches[2]).' grounded start '.resolvePokemon($matches[1]);
  1288.                 }
  1289.                 else if (preg_match('/^\<([^<>]+)\'s substitute blocked ([^<>]+)!\>$/', $line, $matches))
  1290.                 {
  1291.                         $out[] = '  r-sub-block '.resolvePokemon($matches[1]).' '.resolveMove($matches[2]);
  1292.                 }
  1293.                 else if (preg_match('/^\<(.+?): \>([^<>]+)$/', $line, $matches))
  1294.                 {
  1295.                         $out[] = 'chat '.resolveUsername($matches[1]).' '.$matches[2];
  1296.                 }
  1297.                 else if (preg_match('/^\<(.+?): \>\<([^<>]+)\>$/', $line, $matches))
  1298.                 {
  1299.                         $out[] = 'chat '.resolveUsername($matches[1]).' '.$matches[2];
  1300.                 }
  1301.                 else if (preg_match('/^\<(.+?)\>: ([^<>]+)$/', $line, $matches))
  1302.                 {
  1303.                         $out[] = 'chat '.resolveUsername($matches[1]).' '.$matches[2];
  1304.                 }
  1305.                 else if (preg_match('/^\<([^<>]+) flung its ([^<>]+)!\>$/', $line, $matches))
  1306.                 {
  1307.                         $out[] = '  r-fling '.resolvePokemon($matches[1]).' '.resolveItem($matches[2]);
  1308.                 }
  1309.                 else if (preg_match('/^([^<>]+) ate its ([^<>]+)!$/', $line, $matches))
  1310.                 {
  1311.                         $out[] = '  r-eat '.resolvePokemon($matches[1]).' '.resolveItem($matches[2]);
  1312.                 }
  1313.                 else if (preg_match('/^([^<>]+)\'s ([a-zA-Z .\']+) weakened ([^<>]+)\'s power!$/', $line, $matches))
  1314.                 {
  1315.                         $out[] = '  r-weaken '.resolvePokemon($matches[1]).' '.resolveMove($matches[3]).' '.resolveItem($matches[2]);
  1316.                 }
  1317.                 else if (preg_match('/^\<([^<>]+) stole and ate ([^<>]+)\'s ([^<>]+)!\>$/', $line, $matches))
  1318.                 {
  1319.                         $out[] = '  r-steal-eat '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]).' '.resolveItem($matches[3]);
  1320.                 }
  1321.                 else if (preg_match('/^\<([^<>]+)\'s Storm Drain raised its special attack!\>$/', $line, $matches))
  1322.                 {
  1323.                         $out[] = '  r-ability-boost '.resolvePokemon($matches[1]).' spa 1 StormDrain';
  1324.                 }
  1325.                 else if (preg_match('/^\<?([^<>]+)\'s Competitive Spirit sharply raised its Attack!\>?$/', $line, $matches))
  1326.                 {
  1327.                         $out[] = '  r-ability-boost '.resolvePokemon($matches[1]).' atk 2 CompetitiveSpirit';
  1328.                 }
  1329.                 else if (preg_match('/^\<?([^<>]+)\'s Lightningrod raised its (Special Attack|special attack)!\>?$/', $line, $matches))
  1330.                 {
  1331.                         $out[] = '  r-ability-boost '.resolvePokemon($matches[1]).' spa 1 Lightningrod';
  1332.                 }
  1333.                 else if (preg_match('/^\<?([^<>]+)\'s (Justified|Justice Heart) raised its attack!\>?$/', $line, $matches))
  1334.                 {
  1335.                         $out[] = '  r-ability-boost '.resolvePokemon($matches[1]).' atk 1 Justified';
  1336.                 }
  1337.                 else if (preg_match('/^\<?([^<>]+)\'s (Herbivore|Sap Sipper) raised its attack!\>?$/', $line, $matches))
  1338.                 {
  1339.                         $out[] = '  r-ability-boost '.resolvePokemon($matches[1]).' atk 1 SapSipper';
  1340.                 }
  1341.                 else if (preg_match('/^\<?([^<>]+)\'s Motor Drive raise(d|s) its speed!\>?$/', $line, $matches))
  1342.                 {
  1343.                         $out[] = '  r-ability-boost '.resolvePokemon($matches[1]).' spe 1 MotorDrive';
  1344.                 }
  1345.                 else if (preg_match('/^\<?([^<>]+)\'s (Steadfast|SteadFast) increases its speed!\>?$/', $line, $matches))
  1346.                 {
  1347.                         $out[] = '  r-ability-boost '.resolvePokemon($matches[1]).' spe 1 Steadfast';
  1348.                 }
  1349.                 else if (preg_match('/^([^<>]+)\'s Absorb Bulb raised its Sp. Att.!$/', $line, $matches))
  1350.                 {
  1351.                         $out[] = '  r-ability-boost '.resolvePokemon($matches[1]).' spa 1 AbsorbBulb';
  1352.                 }
  1353.                 else if (preg_match('/^([^<>]+)\'s (Moody|Inconsistent) sharply raises its ([a-zA-Z .\']+)!$/', $line, $matches))
  1354.                 {
  1355.                         $out[] = '  r-ability-boost '.resolvePokemon($matches[1]).' '.resolveStat($matches[3]).' 2 Moody';
  1356.                 }
  1357.                 else if (preg_match('/^([^<>]+)\'s (Moody|Inconsistent) lowers its ([a-zA-Z .\']+)!$/', $line, $matches))
  1358.                 {
  1359.                         $out[] = '  r-ability-unboost '.resolvePokemon($matches[1]).' '.resolveStat($matches[3]).' 1 Moody';
  1360.                 }
  1361.                 else if (preg_match('/^([^<>]+)\'s ([a-zA-Z .\']+) raised ([^<>]+)\'s power!$/', $line, $matches))
  1362.                 {
  1363.                         $out[] = '  r-gem '.resolvePokemon($matches[1]).' '.resolveItem($matches[2]).' '.resolveMove($matches[3]).'';
  1364.                 }
  1365.                 else if (preg_match('/^The ([a-zA-Z .\']+) raised ([^<>]+)\'s ([a-zA-Z .\']+)!$/', $line, $matches))
  1366.                 {
  1367.                         $out[] = '  r-item-boost '.resolvePokemon($matches[2]).' '.resolveStat($matches[3]).' 1 '.resolveItem($matches[1]).'';
  1368.                 }
  1369.                 else if (preg_match('/^\<([^<>]+) switched items with ([^<>]+)!\>$/', $line, $matches))
  1370.                 {
  1371.                         $out[] = '  r-trick '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]);
  1372.                 }
  1373.                 else if (preg_match('/^<([^<>]+) obtained one ([a-zA-Z .\']+)!>$/', $line, $matches))
  1374.                 {
  1375.                         $out[] = '  r-trick-get '.resolvePokemon($matches[1]).' '.resolveItem($matches[2]).'';
  1376.                 }
  1377.                 else if (preg_match('/^([^<>]+)\'s ([a-zA-Z .]+) drastically rose!$/', $line, $matches))
  1378.                 {
  1379.                         $out[] = '  r-boost '.resolvePokemon($matches[1]).' '.resolveStat($matches[2]).' 3';
  1380.                 }
  1381.                 else if (preg_match('/^([^<>]+)\'s ([a-zA-Z .]+) sharply rose!$/', $line, $matches))
  1382.                 {
  1383.                         if ($lastmove === 'TailGlow')
  1384.                         {
  1385.                                 $out[] = '  r-boost '.resolvePokemon($matches[1]).' '.resolveStat($matches[2]).' 3';
  1386.                         }
  1387.                         else
  1388.                         {
  1389.                                 $out[] = '  r-boost '.resolvePokemon($matches[1]).' '.resolveStat($matches[2]).' 2';
  1390.                         }
  1391.                 }
  1392.                 else if (preg_match('/^([^<>]+)\'s ([a-zA-Z .]+) rose!$/', $line, $matches))
  1393.                 {
  1394.                         $out[] = '  r-boost '.resolvePokemon($matches[1]).' '.resolveStat($matches[2]).' 1';
  1395.                 }
  1396.                 else if (preg_match('/^\<([^<>]+) stockpiled ([1-3])!\>$/', $line, $matches))
  1397.                 {
  1398.                         $out[] = '  r-volatile '.resolvePokemon($matches[1]).' stockpile'.$matches[2];
  1399.                 }
  1400.                 else if (preg_match('/^\<([^<>]+)\'s perish count fell to ([0-3]).\>$/', $line, $matches))
  1401.                 {
  1402.                         $out[] = '  r-volatile '.resolvePokemon($matches[1]).' perish'.$matches[2];
  1403.                         if ($matches[2] === '0') markLastDamage($out);
  1404.                 }
  1405.                 else if (preg_match('/^([^<>]+) intimidates ([^<>]+)!$/', $line, $matches))
  1406.                 {
  1407.                         $out[] = '  r-intimidate '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]);
  1408.                 }
  1409.                 else if (preg_match('/^\<([^<>]+) moved its status onto ([^<>]+)!\>$/', $line, $matches))
  1410.                 {
  1411.                         $out[] = '  r-psycho-shift '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]);
  1412.                 }
  1413.                 else if (preg_match('/^\<([^<>]+) took ([^<>]+) down with it!\>$/', $line, $matches))
  1414.                 {
  1415.                         $out[] = '  r-also-ko '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]);
  1416.                         markLastDamage($out);
  1417.                 }
  1418.                 else if (preg_match('/^\<The poison spikes disappeared around ([^<>]+)\'s feet!\>$/', $line, $matches))
  1419.                 {
  1420.                         $out[] = '  r-absorb-spikes '.resolvePokemon($matches[1]).' ToxicSpikes';
  1421.                 }
  1422.                 else if (preg_match('/^\<([^<>]+) lost some HP because of Solar Power!\>$/', $line, $matches))
  1423.                 {
  1424.                         $out[] = 'residual '.resolvePokemon($matches[1]).' ability-damage SolarPower ??';
  1425.                         markLastDamage($out);
  1426.                 }
  1427.                 else if (preg_match('/^\<([^<>]+)\'s ([A-Z][a-z]+) Absorb absorbs the attack!\>$/', $line, $matches))
  1428.                 {
  1429.                         $out[] = '  r-ability-heal '.resolvePokemon($matches[1]).' '.$matches[2].'Absorb ??';
  1430.                 }
  1431.                 else if (preg_match('/^\<([^<>]+)\'s ([A-Z][a-z]+) Absorb made the attack useless!\>$/', $line, $matches))
  1432.                 {
  1433.                         $out[] = '  r-ability-heal '.resolvePokemon($matches[1]).' '.$matches[2].'Absorb ??';
  1434.                 }
  1435.                 else if (preg_match('/^([^<>]+)\'s Iron Barbs hurts ([^<>]+)$/', $line, $matches))
  1436.                 {
  1437.                         $out[] = '  r-ability-damage '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]).' IronBarbs ??';
  1438.                         resolvePokemon($matches[2]);
  1439.                         markLastDamage($out);
  1440.                 }
  1441.                 else if (preg_match('/^([^<>]+)\'s Rough Skin hurts ([^<>]+)$/', $line, $matches))
  1442.                 {
  1443.                         $out[] = '  r-ability-damage '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]).' RoughSkin ??';
  1444.                         resolvePokemon($matches[2]);
  1445.                         markLastDamage($out);
  1446.                 }
  1447.                 else if (preg_match('/^([^<>]+)\'s Aftermath damages ([^<>]+)!$/', $line, $matches))
  1448.                 {
  1449.                         $out[] = '  r-ability-damage '.resolvePokemon($matches[1]).' '.resolvePokemon($matches[2]).' Aftermath ??';
  1450.                         resolvePokemon($matches[2]);
  1451.                         markLastDamage($out);
  1452.                 }
  1453.                 else if (preg_match('/^\<([^<>]+)\'s ([^<>]+) was bounced back by Magic Mirror!\>$/', $line, $matches))
  1454.                 {
  1455.                         $out[] = '  r-bounce-back '.resolvePokemon($matches[1]).' MagicMirror '.resolveMove($matches[2]);
  1456.                 }
  1457.                 else if (preg_match('/^\<([^<>]+)\'s ([^<>]+) was bounced back by Magic Coat!\>$/', $line, $matches))
  1458.                 {
  1459.                         $out[] = '  r-bounce-back '.resolvePokemon($matches[1]).' MagicCoat '.resolveMove($matches[2]);
  1460.                 }
  1461.                 else if (preg_match('/^\<Battle between ([^<>]+) and ([^<>]+) is underway!\>$/', $line, $matches))
  1462.                 {
  1463.                         $out[] = 'player '.$matches[1];
  1464.                         $out[] = 'foe-player '.$matches[2];
  1465.                         $out[] = 'start';
  1466.                         $allyname = resolveUsername($matches[1]);
  1467.                         $playernames = array($matches[1],$matches[2]);
  1468.                         $english = 'warn';
  1469.                 }
  1470.                 else if (preg_match('/^\<Battle between ([^<>]+) and ([^<>]+) started!\>$/', $line, $matches))
  1471.                 {
  1472.                         if ($allyname === '' && $convertloopnum === 0)
  1473.                         {
  1474.                                 $convertNotDone = true;
  1475.                         }
  1476.                         else if ($allyname === resolveUsername($matches[1]) || (substr($allyname, 0,6) === 'foeof-' && substr($allyname, 6) === resolveUsername($matches[2])))
  1477.                         {
  1478.                                 $out[] = 'player '.$matches[1];
  1479.                                 $out[] = 'foe-player '.$matches[2];
  1480.                                 $out[] = 'start';
  1481.                                 $allyname = resolveUsername($matches[1]);
  1482.                                 $playernames = array($matches[1],$matches[2]);
  1483.                         }
  1484.                         else
  1485.                         {
  1486.                                 $out[] = 'player '.$matches[2];
  1487.                                 $out[] = 'foe-player '.$matches[1];
  1488.                                 $out[] = 'start';
  1489.                                 $allyname = resolveUsername($matches[2]);
  1490.                                 $playernames = array($matches[2],$matches[1]);
  1491.                         }
  1492.                         $english = true;
  1493.                 }
  1494.                 else if (preg_match('/^\<([^<>]+) won the battle!\>$/', $line, $matches))
  1495.                 {
  1496.                         $winner = $matches[1];
  1497.                 }
  1498.                 else if (preg_match('/^\<Tie between ([^<>]+) and ([^<>]+)!\>$/', $line, $matches))
  1499.                 {
  1500.                         $winner = true;
  1501.                 }
  1502.                 else if (preg_match('/^Hit ([0-9]) times!$/', $line, $matches))
  1503.                 {
  1504.                         $out[] = '  r-hit-count '.$movetarget.' '.$matches[1];
  1505.                 }
  1506.                 else
  1507.                 {
  1508.                         $out[] = 'unknown-effect '.$newline;
  1509.                 }
  1510.                 if ($returnNow)
  1511.                 {
  1512.                         return false;
  1513.                 }
  1514.         }
  1515.        
  1516.         if (!$english)
  1517.         {
  1518.                 $convertNotDone = false;
  1519.                 if (@$_REQUEST['dev']) echo '"'.implode("\n", $text).'"';
  1520.                 return array('error Replay file must be an English Pokemon Online replay file.');
  1521.         }
  1522.         if ($switchcounter === 104)
  1523.         {
  1524.                 return array('error Double battles are not supported (neither are triples, for that matter).');
  1525.         }
  1526.         if ($switchcounter === 106)
  1527.         {
  1528.                 return array('error Triple battles are not supported (neither are doubles, for that matter).');
  1529.         }
  1530.        
  1531.         if ($winner === true) $out[] = 'tie';
  1532.         else if ($winner) $out[] = 'win '.$winner;
  1533.         else $out[] = 'premature-end';
  1534.        
  1535.         foreach ($currentpokemon as $poke)
  1536.         {
  1537.                 $oldlinesoffset++;
  1538.                 array_unshift($out, 'pokemon '.$poke);
  1539.         }
  1540.         {
  1541.                 $oldlinesoffset++;
  1542.                 array_unshift($out, 'gen '.$GLOBALS['gen']);
  1543.         }
  1544.         if ($english === 'warn' && $switchcounter !== 102)
  1545.         {
  1546.                 $oldlinesoffset++;
  1547.                 array_unshift($out, 'warning This is a spectator replay. Crashes may occur since the game may have been joined midway-through.');
  1548.         }
  1549.        
  1550.         return $out;
  1551.  
  1552. }
  1553.  
  1554.  
  1555. function convertById($name)
  1556. {
  1557.         global $REPLAYS;
  1558.         if (!$REPLAYS[$name])
  1559.         {
  1560.                 return;
  1561.         }
  1562.         $text = file_get_contents("uploads/$name.html");
  1563.        
  1564.         $out = pokeConvert($text);
  1565.        
  1566.         if (substr($out[0],0,6) === 'error ')
  1567.         {
  1568.                 return $out;
  1569.         }
  1570.        
  1571.         $fp = fopen("uploads/$name.js",'w');
  1572.        
  1573.         fwrite($fp, "var newlog = [\n");
  1574.         foreach ($out as $line)
  1575.         {
  1576.                 fwrite($fp, "'".addcslashes($line,"'\\")."', \n");
  1577.         }
  1578.         fwrite($fp, "''];");
  1579.         fclose($fp);
  1580.        
  1581.         $fp = fopen("uploads/$name.txt",'w');
  1582.         foreach ($out as $line) fwrite($fp, $line."\r\n");
  1583.         fclose($fp);
  1584.        
  1585.         $REPLAYS[$name]['unidentified'] = array();
  1586.         $REPLAYS[$name]['tags'] = array();
  1587.         $lsreflect = array();
  1588.         foreach ($out as $line)
  1589.         {
  1590.                 if (startsWith($line, '  r-bounce-back ') && strpos($line, ' MagicCoat '))
  1591.                         $REPLAYS[$name]['tags'][] = 'Magic Coat';
  1592.                 if (startsWith($line, '  r-transform '))
  1593.                         $REPLAYS[$name]['tags'][] = 'Transform';
  1594.                 if (startsWith($line, 'move ') && strpos($line, ' RelicSong '))
  1595.                         $REPLAYS[$name]['tags'][] = 'Relic Song';
  1596.                 if (endsWith($line, ' LightScreen'))
  1597.                         $lsreflect['ls'] = true;
  1598.                 if (endsWith($line, ' Reflect'))
  1599.                         $lsreflect['r'] = true;
  1600.                 if (endsWith($line, ' LightScreen end'))
  1601.                         $lsreflect['ls'] = false;
  1602.                 if (endsWith($line, ' Reflect end'))
  1603.                         $lsreflect['r'] = false;
  1604.                 if (startsWith($line, 'unknown-effect '))
  1605.                         $REPLAYS[$name]['unidentified'][] = $line;
  1606.                 if (startsRemove($line, 'error '))
  1607.                         $REPLAYS[$name]['error'] = $line;
  1608.                 if (startsRemove($line, 'warning '))
  1609.                         $REPLAYS[$name]['tags'][] = 'Warning: '.$line;
  1610.                
  1611.                 if ($lsreflect['r'] && $lsreflect['ls'])
  1612.                 {
  1613.                         $REPLAYS[$name]['tags'][] = 'Dual Screens';
  1614.                         $lsreflect = array();
  1615.                 }
  1616.         }
  1617.         if (!$REPLAYS[$name]['unidentified']) unset($REPLAYS[$name]['unidentified']);
  1618.         persist_save('REPLAYS');
  1619.         return $out;
  1620. }