Advertisement
polectron

Untitled

Feb 2nd, 2019
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 75.85 KB | None | 0 0
  1. ################################################################################
  2. # General purpose utilities
  3. ################################################################################
  4. def _pbNextComb(comb,length)
  5.   i=comb.length-1
  6.   begin
  7.     valid=true
  8.     for j in i...comb.length
  9.       if j==i
  10.         comb[j]+=1
  11.       else
  12.         comb[j]=comb[i]+(j-i)
  13.       end
  14.       if comb[j]>=length
  15.         valid=false
  16.         break
  17.       end
  18.     end
  19.     return true if valid
  20.     i-=1
  21.   end while i>=0
  22.   return false
  23. end
  24.  
  25. # Iterates through the array and yields each combination of _num_ elements in
  26. # the array.
  27. def pbEachCombination(array,num)
  28.   return if array.length<num || num<=0
  29.   if array.length==num
  30.     yield array
  31.     return
  32.   elsif num==1
  33.     for x in array
  34.       yield [x]
  35.     end
  36.     return
  37.   end
  38.   currentComb=[]
  39.   arr=[]
  40.   for i in 0...num
  41.     currentComb[i]=i
  42.   end
  43.   begin
  44.     for i in 0...num
  45.       arr[i]=array[currentComb[i]]
  46.     end
  47.     yield arr
  48.   end while _pbNextComb(currentComb,array.length)
  49. end
  50.  
  51. def pbGetCDID()
  52.   sendString=proc{|x|
  53.      mciSendString=Win32API.new('winmm','mciSendString','%w(p,p,l,l)','l')
  54.      next "" if !mciSendString
  55.      buffer="\0"*2000
  56.      x=mciSendString.call(x,buffer,2000,0)
  57.      if x==0
  58.        next buffer.gsub(/\0/,"")
  59.      else
  60.        next ""
  61.      end
  62.   }
  63.   sendString.call("open cdaudio shareable")
  64.   ret=""
  65.   if sendString.call("status cdaudio media present")=="true"
  66.     ret=sendString.call("info cdaudio identity")
  67.     if ret==""
  68.       ret=sendString.call("info cdaudio info identity")
  69.     end
  70.   end
  71.   sendString.call("close cdaudio")
  72.   return ret
  73. end
  74.  
  75. # Gets the path of the user's "My Documents" folder.
  76. def pbGetMyDocumentsFolder()
  77.   csidl_personal=0x0005
  78.   shGetSpecialFolderLocation=Win32API.new("shell32.dll","SHGetSpecialFolderLocation","llp","i")
  79.   shGetPathFromIDList=Win32API.new("shell32.dll","SHGetPathFromIDList","lp","i")
  80.   if !shGetSpecialFolderLocation || !shGetPathFromIDList
  81.     return "."
  82.   end
  83.   idl=[0].pack("V")
  84.   ret=shGetSpecialFolderLocation.call(0,csidl_personal,idl)
  85.   return "." if ret!=0
  86.   path="\0"*512
  87.   ret=shGetPathFromIDList.call(idl.unpack("V")[0],path)
  88.   return "." if ret==0
  89.   return path.gsub(/\0/,"")
  90. end
  91.  
  92. # Returns a country ID
  93. # http://msdn.microsoft.com/en-us/library/dd374073%28VS.85%29.aspx?
  94. def pbGetCountry()
  95.   getUserGeoID=Win32API.new("kernel32","GetUserGeoID","l","i") rescue nil
  96.   if getUserGeoID
  97.     return getUserGeoID.call(16)
  98.   end
  99.   return 0
  100. end
  101.  
  102. # Returns a language ID
  103. def pbGetLanguage()
  104.   getUserDefaultLangID=Win32API.new("kernel32","GetUserDefaultLangID","","i") rescue nil
  105.   ret=0
  106.   if getUserDefaultLangID
  107.     ret=getUserDefaultLangID.call()&0x3FF
  108.   end
  109.   if ret==0 # Unknown
  110.     ret=MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER,
  111.        "Control Panel\\Desktop\\ResourceLocale","",0)
  112.     ret=MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER,
  113.        "Control Panel\\International","Locale","0").to_i(16) if ret==0
  114.     ret=ret&0x3FF
  115.     return 0 if ret==0  # Unknown
  116.   end
  117.   return 1 if ret==0x11 # Japanese
  118.   return 2 if ret==0x09 # English
  119.   return 3 if ret==0x0C # French
  120.   return 4 if ret==0x10 # Italian
  121.   return 5 if ret==0x07 # German
  122.   return 7 if ret==0x0A # Spanish
  123.   return 8 if ret==0x12 # Korean
  124.   return 2 # Use 'English' by default
  125. end
  126.  
  127. # Converts a Celsius temperature to Fahrenheit.
  128. def toFahrenheit(celsius)
  129.   return (celsius*9.0/5.0).round+32
  130. end
  131.  
  132. # Converts a Fahrenheit temperature to Celsius.
  133. def toCelsius(fahrenheit)
  134.   return ((fahrenheit-32)*5.0/9.0).round
  135. end
  136.  
  137.  
  138.  
  139. ################################################################################
  140. # Linear congruential random number generator
  141. ################################################################################
  142. class LinearCongRandom
  143.   def initialize(mul, add, seed=nil)
  144.     @s1=mul
  145.     @s2=add
  146.     @seed=seed
  147.     @seed=(Time.now.to_i&0xffffffff) if !@seed
  148.     @seed=(@seed+0xFFFFFFFF)+1 if @seed<0
  149.   end
  150.  
  151.   def self.dsSeed
  152.     t=Time.now
  153.     seed = (((t.mon * t.mday + t.min + t.sec)&0xFF) << 24) | (t.hour << 16) | (t.year - 2000)
  154.     seed=(seed+0xFFFFFFFF)+1 if seed<0
  155.     return seed
  156.   end
  157.  
  158.   def self.pokemonRNG
  159.     self.new(0x41c64e6d,0x6073,self.dsSeed)
  160.   end
  161.  
  162.   def self.pokemonRNGInverse
  163.     self.new(0xeeb9eb65,0xa3561a1,self.dsSeed)
  164.   end
  165.  
  166.   def self.pokemonARNG
  167.     self.new(0x6C078965,0x01,self.dsSeed)
  168.   end
  169.  
  170.   def getNext16 # calculates @seed * @s1 + @s2
  171.     @seed=((((@seed & 0x0000ffff) * (@s1 & 0x0000ffff)) & 0x0000ffff) |
  172.        (((((((@seed & 0x0000ffff) * (@s1 & 0x0000ffff)) & 0xffff0000) >> 16) +
  173.        ((((@seed & 0xffff0000) >> 16) * (@s1 & 0x0000ffff)) & 0x0000ffff) +
  174.        (((@seed & 0x0000ffff) * ((@s1 & 0xffff0000) >> 16)) & 0x0000ffff)) &
  175.        0x0000ffff) << 16)) + @s2
  176.     r=(@seed>>16)
  177.     r=(r+0xFFFFFFFF)+1 if r<0
  178.     return r
  179.   end
  180.  
  181.   def getNext
  182.     r=(getNext16()<<16)|(getNext16())
  183.     r=(r+0xFFFFFFFF)+1 if r<0
  184.     return r
  185.   end
  186. end
  187.  
  188.  
  189.  
  190. ################################################################################
  191. # JavaScript-related utilities
  192. ################################################################################
  193. # Returns true if the given string represents a valid object in JavaScript
  194. # Object Notation, and false otherwise.
  195. def  pbIsJsonString(str)
  196.   return false if (!str || str[ /^[\s]*$/ ])
  197.   d=/(?:^|:|,)(?: ?\[)+/
  198.   charEscapes=/\\[\"\\\/nrtubf]/ #"
  199.   stringLiterals=/"[^"\\\n\r\x00-\x1f\x7f-\x9f]*"/ #"
  200.   whiteSpace=/[\s]+/
  201.   str=str.gsub(charEscapes,"@").gsub(stringLiterals,"true").gsub(whiteSpace," ")
  202.   # prevent cases like "truetrue" or "true true" or "true[true]" or "5-2" or "5true"
  203.   otherLiterals=/(true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)(?! ?[0-9a-z\-\[\{\"])/ #"
  204.   str=str.gsub(otherLiterals,"]").gsub(d,"") #"
  205.   p str
  206.   return str[ /^[\],:{} ]*$/ ] ? true : false
  207. end
  208.  
  209. # Returns a Ruby object that corresponds to the given string, which is encoded in
  210. # JavaScript Object Notation (JSON). Returns nil if the string is not valid JSON.
  211. def pbParseJson(str)
  212.   if !pbIsJsonString(str)
  213.     return nil
  214.   end
  215.   stringRE=/(\"(\\[\"\'\\rntbf]|\\u[0-9A-Fa-f]{4,4}|[^\\\"])*\")/ #"
  216.   strings=[]
  217.   str=str.gsub(stringRE){
  218.      sl=strings.length
  219.      ss=$1
  220.      if ss.include?("\\u")
  221.        ss.gsub!(/\\u([0-9A-Fa-f]{4,4})/){
  222.           codepoint=$1.to_i(16)
  223.           if codepoint<=0x7F
  224.             next sprintf("\\x%02X",codepoint)
  225.           elsif codepoint<=0x7FF
  226.             next sprintf("%s%s",
  227.                (0xC0|((codepoint>>6)&0x1F)).chr,
  228.                (0x80|(codepoint   &0x3F)).chr)
  229.           else
  230.             next sprintf("%s%s%s",
  231.                (0xE0|((codepoint>>12)&0x0F)).chr,
  232.                (0x80|((codepoint>>6)&0x3F)).chr,
  233.                (0x80|(codepoint   &0x3F)).chr)
  234.           end
  235.        }
  236.      end
  237.      strings.push(eval(ss))
  238.      next sprintf("strings[%d]",sl)
  239.   }
  240.   str=str.gsub(/\:/,"=>")
  241.   str=str.gsub(/null/,"nil")
  242.   return eval("("+str+")")
  243. end
  244.  
  245.  
  246.  
  247. ################################################################################
  248. # XML-related utilities
  249. ################################################################################
  250. # Represents XML content.
  251. class MiniXmlContent
  252.   attr_reader :value
  253.  
  254.   def initialize(value)
  255.     @value=value
  256.   end
  257. end
  258.  
  259.  
  260.  
  261. # Represents an XML element.
  262. class MiniXmlElement
  263.   attr_accessor :name,:attributes,:children
  264.  
  265.   def initialize(name)
  266.     @name=name
  267.     @attributes={}
  268.     @children=[]
  269.   end
  270.  
  271. #  Gets the value of the attribute with the given name, or nil if it doesn't
  272. #  exist.
  273.   def a(name)
  274.     self.attributes[name]
  275.   end
  276.  
  277. #  Gets the entire text of this element.
  278.   def value
  279.     ret=""
  280.     for c in @children
  281.       ret+=c.value
  282.     end
  283.     return ret
  284.   end
  285.  
  286. #  Gets the first child of this element with the given name, or nil if it
  287. # doesn't exist.
  288.   def e(name)
  289.     for c in @children
  290.       return c if c.is_a?(MiniXmlElement) && c.name==name
  291.     end
  292.     return nil
  293.   end
  294.  
  295.   def eachElementNamed(name)
  296.     for c in @children
  297.       yield c if c.is_a?(MiniXmlElement) && c.name==name
  298.     end
  299.   end
  300. end
  301.  
  302.  
  303.  
  304. # A small class for reading simple XML documents. Such documents must
  305. # meet the following restrictions:
  306. #  They may contain comments and processing instructions, but they are
  307. #    ignored.
  308. #  They can't contain any entity references other than 'gt', 'lt',
  309. #    'amp', 'apos', or 'quot'.
  310. #  They can't contain a DOCTYPE declaration or DTDs.
  311. class MiniXmlReader
  312.   def initialize(data)
  313.     @root=nil
  314.     @elements=[]
  315.     @done=false
  316.     @data=data
  317.     @content=""
  318.   end
  319.  
  320.   def createUtf8(codepoint) #:nodoc:
  321.     raise ArgumentError.new("Illegal character") if codepoint<9 ||
  322.        codepoint==11||codepoint==12||(codepoint>=14 && codepoint<32) ||
  323.        codepoint==0xFFFE||codepoint==0xFFFF||(codepoint>=0xD800 && codepoint<0xE000)
  324.     if codepoint<=0x7F
  325.       return codepoint.chr
  326.     elsif codepoint<=0x7FF
  327.       str=(0xC0|((codepoint>>6)&0x1F)).chr
  328.       str+=(0x80|(codepoint   &0x3F)).chr
  329.       return str
  330.     elsif codepoint<=0xFFFF
  331.       str=(0xE0|((codepoint>>12)&0x0F)).chr
  332.       str+=(0x80|((codepoint>>6)&0x3F)).chr
  333.       str+=(0x80|(codepoint   &0x3F)).chr
  334.       return str
  335.     elsif codepoint<=0x10FFFF
  336.       str=(0xF0|((codepoint>>18)&0x07)).chr
  337.       str+=(0x80|((codepoint>>12)&0x3F)).chr
  338.       str+=(0x80|((codepoint>>6)&0x3F)).chr
  339.       str+=(0x80|(codepoint   &0x3F)).chr
  340.       return str
  341.     else
  342.       raise ArgumentError.new("Illegal character")
  343.     end
  344.     return str
  345.   end
  346.  
  347.   def unescape(attr) #:nodoc:
  348.     attr=attr.gsub(/\r(\n|$|(?=[^\n]))/,"\n")
  349.     raise ArgumentError.new("Attribute value contains '<'") if attr.include?("<")
  350.     attr=attr.gsub(/&(lt|gt|apos|quot|amp|\#([0-9]+)|\#x([0-9a-fA-F]+));|([\n\r\t])/){
  351.        next " " if $4=="\n"||$4=="\r"||$4=="\t"
  352.        next "<" if $1=="lt"
  353.        next ">" if $1=="gt"
  354.        next "'" if $1=="apos"
  355.        next "\"" if $1=="quot"
  356.        next "&" if $1=="amp"
  357.        next createUtf8($2.to_i) if $2
  358.        next createUtf8($3.to_i(16)) if $3
  359.     }
  360.     return attr
  361.   end
  362.  
  363.   def readAttributes(attribs) #:nodoc:
  364.     ret={}
  365.     while attribs.length>0
  366.       if attribs[/(\s+([\w\-]+)\s*\=\s*\"([^\"]*)\")/]
  367.        attribs=attribs[$1.length,attribs.length]
  368.        name=$2; value=$3
  369.        if ret[name]!=nil
  370.          raise ArgumentError.new("Attribute already exists")
  371.        end
  372.        ret[name]=unescape(value)
  373.      elsif attribs[/(\s+([\w\-]+)\s*\=\s*\'([^\']*)\')/]
  374.        attribs=attribs[$1.length,attribs.length]
  375.        name=$2; value=$3
  376.        if ret[name]!=nil
  377.          raise ArgumentError.new("Attribute already exists")
  378.        end
  379.        ret[name]=unescape(value)
  380.      else
  381.        raise ArgumentError.new("Can't parse attributes")
  382.      end
  383.    end
  384.    return ret
  385.  end
  386.  
  387. # Reads the entire contents of an XML document. Returns the root element of
  388. # the document or raises an ArgumentError if an error occurs.
  389.  def read
  390.    if @data[/\A((\xef\xbb\xbf)?<\?xml\s+version\s*=\s*(\"1\.[0-9]\"|\'1\.[0-9]\')(\s+encoding\s*=\s*(\"[^\"]*\"|\'[^\']*\'))?(\s+standalone\s*=\s*(\"(yes|no)\"|\'(yes|no)\'))?\s*\?>)/]
  391.      # Ignore XML declaration
  392.      @data=@data[$1.length,@data.length]
  393.    end
  394.    while readOneElement(); end
  395.    return @root
  396.  end
  397.  
  398.  def readOneElement #:nodoc:
  399.    if @data[/\A\s*\z/]
  400.      @data=""
  401.      if !@root
  402.        raise ArgumentError.new("Not an XML document.")
  403.      elsif !@done
  404.        raise ArgumentError.new("Unexpected end of document.")
  405.      end
  406.      return false
  407.    end
  408.    if @data[/\A(\s*<([\w\-]+)((?:\s+[\w\-]+\s*\=\s*(?:\"[^\"]*\"|\'[^\']*\'))*)\s*(\/>|>))/]
  409.      @data=@data[$1.length,@data.length]
  410.      elementName=$2
  411.      attributes=$3
  412.      endtag=$4
  413.      if @done
  414.        raise ArgumentError.new("Element tag at end of document")
  415.      end
  416.      if @content.length>0 && @elements.length>0
  417.        @elements[@elements.length-1].children.push(MiniXmlContent.new(@content))
  418.        @content=""
  419.      end
  420.      element=MiniXmlElement.new(elementName)
  421.      element.attributes=readAttributes(attributes)
  422.      if !@root
  423.        @root=element
  424.      else
  425.        @elements[@elements.length-1].children.push(element)
  426.      end
  427.      if endtag==">"
  428.        @elements.push(element)
  429.      else
  430.        if @elements.length==0
  431.          @done=true
  432.        end
  433.      end
  434.    elsif @data[/\A(<!--([\s\S]*?)-->)/]
  435.      # ignore comments
  436.      if $2.include?("--")
  437.        raise ArgumentError.new("Incorrect comment")
  438.      end
  439.      @data=@data[$1.length,@data.length]
  440.    elsif @data[/\A(<\?([\w\-]+)\s+[\s\S]*?\?>)/]
  441.      # ignore processing instructions
  442.      @data=@data[$1.length,@data.length]
  443.      if $2.downcase=="xml"
  444.        raise ArgumentError.new("'xml' processing instruction not allowed")
  445.      end
  446.    elsif @data[/\A(<\?([\w\-]+)\?>)/]
  447.      # ignore processing instructions
  448.      @data=@data[$1.length,@data.length]
  449.      if $2.downcase=="xml"
  450.        raise ArgumentError.new("'xml' processing instruction not allowed")
  451.      end
  452.    elsif @data[/\A(\s*<\/([\w\-]+)>)/]
  453.      @data=@data[$1.length,@data.length]
  454.      elementName=$2
  455.      if @done
  456.        raise ArgumentError.new("End tag at end of document")
  457.      end
  458.      if @elements.length==0
  459.        raise ArgumentError.new("Unexpected end tag")
  460.      elsif @elements[@elements.length-1].name!=elementName
  461.        raise ArgumentError.new("Incorrect end tag")
  462.      else
  463.        if @content.length>0
  464.          @elements[@elements.length-1].children.push(MiniXmlContent.new(@content))
  465.          @content=""
  466.        end
  467.        @elements.pop()
  468.        if @elements.length==0
  469.          @done=true
  470.        end
  471.      end
  472.    else
  473.      if @elements.length>0
  474.        # Parse content
  475.        if @data[/\A([^<&]+)/]
  476.          content=$1
  477.          @data=@data[content.length,@data.length]
  478.          if content.include?("]]>")
  479.            raise ArgumentError.new("Incorrect content")
  480.          end
  481.          content.gsub!(/\r(\n|\z|(?=[^\n]))/,"\n")
  482.          @content+=content
  483.        elsif @data[/\A(<\!\[CDATA\[([\s\S]*?)\]\]>)/]
  484.          content=$2
  485.          @data=@data[$1.length,@data.length]
  486.          content.gsub!(/\r(\n|\z|(?=[^\n]))/,"\n")
  487.          @content+=content
  488.        elsif @data[/\A(&(lt|gt|apos|quot|amp|\#([0-9]+)|\#x([0-9a-fA-F]+));)/]
  489.          @data=@data[$1.length,@data.length]
  490.          content=""
  491.          if $2=="lt"; content="<"
  492.          elsif $2=="gt"; content=">"
  493.          elsif $2=="apos"; content="'"
  494.          elsif  $2=="quot"; content="\""
  495.           elsif $2=="amp"; content="&"
  496.           elsif $3; content=createUtf8($2.to_i)
  497.           elsif $4; content=createUtf8($3.to_i(16))
  498.           end
  499.           @content+=content
  500.         elsif !@data[/\A</]
  501.           raise ArgumentError.new("Can't read XML content")
  502.         end
  503.       else
  504.         raise ArgumentError.new("Can't parse XML")
  505.       end
  506.     end
  507.     return true
  508.   end
  509. end
  510.  
  511.  
  512.  
  513. ################################################################################
  514. # Player-related utilities, random name generator
  515. ################################################################################
  516. def pbChangePlayer(id)
  517.   return false if id<0 || id>=8
  518.   meta=pbGetMetadata(0,MetadataPlayerA+id)
  519.   return false if !meta
  520.   $Trainer.trainertype=meta[0] if $Trainer
  521.   $game_player.character_name=meta[1]
  522.   $game_player.character_hue=0
  523.   $PokemonGlobal.playerID=id
  524.   $Trainer.metaID=id if $Trainer
  525. end
  526.  
  527. def pbGetPlayerGraphic
  528.   id=$PokemonGlobal.playerID
  529.   return "" if id<0 || id>=8
  530.   meta=pbGetMetadata(0,MetadataPlayerA+id)
  531.   return "" if !meta
  532.   return pbPlayerSpriteFile(meta[0])
  533. end
  534.  
  535. def pbGetPlayerTrainerType
  536.   id=$PokemonGlobal.playerID
  537.   return 0 if id<0 || id>=8
  538.   meta=pbGetMetadata(0,MetadataPlayerA+id)
  539.   return 0 if !meta
  540.   return meta[0]
  541. end
  542.  
  543. def pbGetTrainerTypeGender(trainertype)
  544.   ret=2 # 2 = gender unknown
  545.   pbRgssOpen("Data/trainertypes.dat","rb"){|f|
  546.      trainertypes=Marshal.load(f)
  547.      if !trainertypes[trainertype]
  548.        ret=2
  549.      else
  550.        ret=trainertypes[trainertype][7]
  551.        ret=2 if !ret
  552.      end
  553.   }
  554.   return ret
  555. end
  556.  
  557. def pbTrainerName(name=nil,outfit=0)
  558.   if $PokemonGlobal.playerID<0
  559.     pbChangePlayer(0)
  560.   end
  561.   trainertype=pbGetPlayerTrainerType
  562.   trname=name
  563.   $Trainer=PokeBattle_Trainer.new(trname,trainertype)
  564.   $Trainer.outfit=outfit
  565.   if trname==nil
  566.     trname=pbEnterPlayerName(_INTL("Your name?"),0,7)
  567.     if trname==""
  568.       gender=pbGetTrainerTypeGender(trainertype)
  569.       trname="Alma"
  570.     end
  571.   end
  572.   $Trainer.name=trname
  573.   $PokemonBag=PokemonBag.new
  574.   $PokemonTemp.begunNewGame=true
  575. end
  576.  
  577. def pbSuggestTrainerName(gender)
  578.   userName=pbGetUserName()
  579.   userName=userName.gsub(/\s+.*$/,"")
  580.   if userName.length>0 && userName.length<7
  581.     userName[0,1]=userName[0,1].upcase
  582.     return userName
  583.   end
  584.   userName=userName.gsub(/\d+$/,"")
  585.   if userName.length>0 && userName.length<7
  586.     userName[0,1]=userName[0,1].upcase
  587.     return userName
  588.   end
  589.   owner=MiniRegistry.get(MiniRegistry::HKEY_LOCAL_MACHINE,
  590.      "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
  591.      "RegisteredOwner","")
  592.   owner=owner.gsub(/\s+.*$/,"")
  593.   if owner.length>0 && owner.length<7
  594.     owner[0,1]=owner[0,1].upcase
  595.     return owner
  596.   end
  597.   return getRandomNameEx(gender,nil,1,7)
  598. end
  599.  
  600. def pbGetUserName()
  601.   buffersize=100
  602.   getUserName=Win32API.new('advapi32.dll','GetUserName','pp','i')
  603.   10.times do
  604.     size=[buffersize].pack("V")
  605.     buffer="\0"*buffersize
  606.     if getUserName.call(buffer,size)!=0
  607.       return buffer.gsub(/\0/,"")
  608.     end
  609.     buffersize+=200
  610.   end
  611.   return ""
  612. end
  613.  
  614. def getRandomNameEx(type,variable,upper,maxLength=100)
  615.   return "" if maxLength<=0
  616.   name=""
  617.   50.times {
  618.     name=""
  619.     formats=[]
  620.     case type
  621.     when 0 # Names for males
  622.       formats=%w( F5 BvE FE FE5 FEvE )
  623.     when 1 # Names for females
  624.       formats=%w( vE6 vEvE6 BvE6 B4 v3 vEv3 Bv3 )
  625.     when 2 # Neutral gender names
  626.       formats=%w( WE WEU WEvE BvE BvEU BvEvE )
  627.     else
  628.       return ""
  629.     end
  630.     format=formats[rand(formats.length)]
  631.     format.scan(/./) {|c|
  632.        case c
  633.        when "c" # consonant
  634.          set=%w( b c d f g h j k l m n p r s t v w x z )
  635.          name+=set[rand(set.length)]
  636.        when "v" # vowel
  637.          set=%w( a a a e e e i i i o o o u u u )
  638.          name+=set[rand(set.length)]
  639.        when "W" # beginning vowel
  640.          set=%w( a a a e e e i i i o o o u u u au au ay ay
  641.             ea ea ee ee oo oo ou ou )
  642.          name+=set[rand(set.length)]
  643.        when "U" # ending vowel
  644.          set=%w( a a a a a e e e i i i o o o o o u u ay ay ie ie ee ue oo )
  645.          name+=set[rand(set.length)]
  646.        when "B" # beginning consonant
  647.          set1=%w( b c d f g h j k l l m n n p r r s s t t v w y z )
  648.          set2=%w(
  649.             bl br ch cl cr dr fr fl gl gr kh kl kr ph pl pr sc sk sl
  650.             sm sn sp st sw th tr tw vl zh )
  651.          name+=rand(3)>0 ? set1[rand(set1.length)] : set2[rand(set2.length)]
  652.        when "E" # ending consonant
  653.          set1=%w( b c d f g h j k k l l m n n p r r s s t t v z )
  654.          set2=%w( bb bs ch cs ds fs ft gs gg ld ls
  655.             nd ng nk rn kt ks
  656.             ms ns ph pt ps sk sh sp ss st rd
  657.             rn rp rm rt rk ns th zh)
  658.          name+=rand(3)>0 ? set1[rand(set1.length)] : set2[rand(set2.length)]
  659.        when "f" # consonant and vowel
  660.          set=%w( iz us or )
  661.          name+=set[rand(set.length)]
  662.        when "F" # consonant and vowel
  663.          set=%w( bo ba be bu re ro si mi zho se nya gru gruu glee gra glo ra do zo ri
  664.             di ze go ga pree pro po pa ka ki ku de da ma mo le la li )
  665.          name+=set[rand(set.length)]
  666.        when "2"
  667.          set=%w( c f g k l p r s t )
  668.          name+=set[rand(set.length)]
  669.        when "3"
  670.          set=%w( nka nda la li ndra sta cha chie )
  671.          name+=set[rand(set.length)]
  672.        when "4"
  673.          set=%w( una ona ina ita ila ala ana ia iana )
  674.          name+=set[rand(set.length)]
  675.        when "5"
  676.          set=%w( e e o o ius io u u ito io ius us )
  677.          name+=set[rand(set.length)]
  678.        when "6"
  679.          set=%w( a a a elle ine ika ina ita ila ala ana )
  680.          name+=set[rand(set.length)]
  681.        end
  682.     }
  683.     break if name.length<=maxLength
  684.   }
  685.   name=name[0,maxLength]
  686.   case upper
  687.   when 0
  688.     name=name.upcase
  689.   when 1
  690.     name[0,1]=name[0,1].upcase
  691.   end
  692.   if $game_variables && variable
  693.     $game_variables[variable]=name
  694.     $game_map.need_refresh = true if $game_map
  695.   end
  696.   return name
  697. end
  698.  
  699. def getRandomName(maxLength=100)
  700.   return getRandomNameEx(2,nil,nil,maxLength)
  701. end
  702.  
  703.  
  704.  
  705. ################################################################################
  706. # Event timing utilities
  707. ################################################################################
  708. def pbTimeEvent(variableNumber,secs=86400)
  709.   if variableNumber && variableNumber>=0
  710.     if $game_variables
  711.       secs=0 if secs<0
  712.       timenow=pbGetTimeNow
  713.       $game_variables[variableNumber]=[timenow.to_f,secs]
  714.       $game_map.refresh if $game_map
  715.     end
  716.   end
  717. end
  718.  
  719. def pbTimeEventDays(variableNumber,days=0)
  720.   if variableNumber && variableNumber>=0
  721.     if $game_variables
  722.       days=0 if days<0
  723.       timenow=pbGetTimeNow
  724.       time=timenow.to_f
  725.       expiry=(time%86400.0)+(days*86400.0)
  726.       $game_variables[variableNumber]=[time,expiry-time]
  727.       $game_map.refresh if $game_map
  728.     end
  729.   end
  730. end
  731.  
  732. def pbTimeEventValid(variableNumber)
  733.   retval=false
  734.   if variableNumber && variableNumber>=0 && $game_variables
  735.     value=$game_variables[variableNumber]
  736.     if value.is_a?(Array)
  737.       timenow=pbGetTimeNow
  738.       retval=(timenow.to_f - value[0] > value[1]) # value[1] is age in seconds
  739.       retval=false if value[1]<=0 # zero age
  740.     end
  741.     if !retval
  742.       $game_variables[variableNumber]=0
  743.       $game_map.refresh if $game_map
  744.     end
  745.   end
  746.   return retval
  747. end
  748.  
  749.  
  750.  
  751. ################################################################################
  752. # Constants utilities
  753. ################################################################################
  754. def isConst?(val,mod,constant)
  755.   begin
  756.     isdef=mod.const_defined?(constant.to_sym)
  757.     return false if !isdef
  758.   rescue
  759.     return false
  760.   end
  761.   return (val==mod.const_get(constant.to_sym))
  762. end
  763.  
  764. def hasConst?(mod,constant)
  765.   return false if !mod || !constant || constant==""
  766.   return mod.const_defined?(constant.to_sym) rescue false
  767. end
  768.  
  769. def getConst(mod,constant)
  770.   return nil if !mod || !constant || constant==""
  771.   return mod.const_get(constant.to_sym) rescue nil
  772. end
  773.  
  774. def getID(mod,constant)
  775.   return nil if !mod || !constant || constant==""
  776.   if constant.is_a?(Symbol) || constant.is_a?(String)
  777.     if (mod.const_defined?(constant.to_sym) rescue false)
  778.       return mod.const_get(constant.to_sym) rescue 0
  779.     else
  780.       return 0
  781.     end
  782.   else
  783.     return constant
  784.   end
  785. end
  786.  
  787.  
  788.  
  789. ################################################################################
  790. # Implements methods that act on arrays of items.  Each element in an item
  791. # array is itself an array of [itemID, itemCount].
  792. # Used by the Bag, PC item storage, and Triple Triad.
  793. ################################################################################
  794. module ItemStorageHelper
  795.   # Returns the quantity of the given item in the items array, maximum size per slot, and item ID
  796.   def self.pbQuantity(items,maxsize,item)
  797.     ret=0
  798.     for i in 0...maxsize
  799.       itemslot=items[i]
  800.       if itemslot && itemslot[0]==item
  801.         ret+=itemslot[1]
  802.       end
  803.     end
  804.     return ret
  805.   end
  806.  
  807.   # Deletes an item from items array, maximum size per slot, item, and number of items to delete
  808.   def self.pbDeleteItem(items,maxsize,item,qty)
  809.     raise "Invalid value for qty: #{qty}" if qty<0
  810.     return true if qty==0
  811.     ret=false
  812.     for i in 0...maxsize
  813.       itemslot=items[i]
  814.       if itemslot && itemslot[0]==item
  815.         amount=[qty,itemslot[1]].min
  816.         itemslot[1]-=amount
  817.         qty-=amount
  818.         items[i]=nil if itemslot[1]==0
  819.         if qty==0
  820.           ret=true
  821.           break
  822.         end
  823.       end
  824.     end
  825.     items.compact!
  826.     return ret
  827.   end
  828.  
  829.   def self.pbCanStore?(items,maxsize,maxPerSlot,item,qty)
  830.     raise "Invalid value for qty: #{qty}" if qty<0
  831.     return true if qty==0
  832.     for i in 0...maxsize
  833.       itemslot=items[i]
  834.       if !itemslot
  835.         qty-=[qty,maxPerSlot].min
  836.         return true if qty==0
  837.       elsif itemslot[0]==item && itemslot[1]<maxPerSlot
  838.         newamt=itemslot[1]
  839.         newamt=[newamt+qty,maxPerSlot].min
  840.         qty-=(newamt-itemslot[1])
  841.         return true if qty==0
  842.       end
  843.     end
  844.     return false
  845.   end
  846.  
  847.   def self.pbStoreItem(items,maxsize,maxPerSlot,item,qty,sorting=false)
  848.     raise "Invalid value for qty: #{qty}" if qty<0
  849.     return true if qty==0
  850.     for i in 0...maxsize
  851.       itemslot=items[i]
  852.       if !itemslot
  853.         items[i]=[item,[qty,maxPerSlot].min]
  854.         qty-=items[i][1]
  855.         if sorting
  856.           items.sort! if POCKETAUTOSORT[$ItemData[item][ITEMPOCKET]]
  857.         end
  858.         return true if qty==0
  859.       elsif itemslot[0]==item && itemslot[1]<maxPerSlot
  860.         newamt=itemslot[1]
  861.         newamt=[newamt+qty,maxPerSlot].min
  862.         qty-=(newamt-itemslot[1])
  863.         itemslot[1]=newamt
  864.         return true if qty==0
  865.       end
  866.     end
  867.     return false
  868.   end
  869. end
  870.  
  871.  
  872.  
  873. ################################################################################
  874. # General-purpose utilities with dependencies
  875. ################################################################################
  876. # Similar to pbFadeOutIn, but pauses the music as it fades out.
  877. # Requires scripts "Audio" (for bgm_pause) and "SpriteWindow" (for pbFadeOutIn).
  878. def pbFadeOutInWithMusic(zViewport)
  879.   playingBGS=$game_system.getPlayingBGS
  880.   playingBGM=$game_system.getPlayingBGM
  881.   $game_system.bgm_pause(1.0)
  882.   $game_system.bgs_pause(1.0)
  883.   pos=$game_system.bgm_position
  884.   pbFadeOutIn(zViewport) {
  885.      yield
  886.      $game_system.bgm_position=pos
  887.      $game_system.bgm_resume(playingBGM)
  888.      $game_system.bgs_resume(playingBGS)
  889.   }
  890. end
  891.  
  892. # Gets the wave data from a file and displays an message if an error occurs.
  893. # Can optionally delete the wave file (this is useful if the file was a
  894. # temporary file created by a recording).
  895. # Requires the script AudioUtilities
  896. # Requires the script "PokemonMessages"
  897. def getWaveDataUI(filename,deleteFile=false)
  898.   error=getWaveData(filename)
  899.   if deleteFile
  900.     begin
  901.       File.delete(filename)
  902.     rescue Errno::EINVAL, Errno::EACCES, Errno::ENOENT
  903.     end
  904.   end
  905.   case error
  906.   when 1
  907.     Kernel.pbMessage(_INTL("The recorded data could not be found or saved."))
  908.   when 2
  909.     Kernel.pbMessage(_INTL("The recorded data was in an invalid format."))
  910.   when 3
  911.     Kernel.pbMessage(_INTL("The recorded data's format is not supported."))
  912.   when 4
  913.     Kernel.pbMessage(_INTL("There was no sound in the recording. Please ensure that a microphone is attached to the computer and is ready."))
  914.   else
  915.     return error
  916.   end
  917.   return nil
  918. end
  919.  
  920. # Starts recording, and displays a message if the recording failed to start.
  921. # Returns true if successful, false otherwise
  922. # Requires the script AudioUtilities
  923. # Requires the script "PokemonMessages"
  924. def beginRecordUI
  925.   code=beginRecord
  926.   case code
  927.   when 0; return true
  928.   when 256+66
  929.     Kernel.pbMessage(_INTL("All recording devices are in use. Recording is not possible now."))
  930.     return false
  931.   when 256+72
  932.     Kernel.pbMessage(_INTL("No supported recording device was found. Recording is not possible."))
  933.     return false
  934.   else
  935.     buffer="\0"*256
  936.     MciErrorString.call(code,buffer,256)
  937.     Kernel.pbMessage(_INTL("Recording failed: {1}",buffer.gsub(/\x00/,"")))
  938.     return false    
  939.   end
  940. end
  941.  
  942. def pbHideVisibleObjects
  943.   visibleObjects=[]
  944.   ObjectSpace.each_object(Sprite){|o|
  945.      if !o.disposed? && o.visible
  946.        visibleObjects.push(o)
  947.        o.visible=false
  948.      end
  949.   }
  950.   ObjectSpace.each_object(Viewport){|o|
  951.      if !pbDisposed?(o) && o.visible
  952.        visibleObjects.push(o)
  953.        o.visible=false
  954.      end
  955.   }
  956.   ObjectSpace.each_object(Plane){|o|
  957.      if !o.disposed? && o.visible
  958.        visibleObjects.push(o)
  959.        o.visible=false
  960.      end
  961.   }
  962.   ObjectSpace.each_object(Tilemap){|o|
  963.      if !o.disposed? && o.visible
  964.        visibleObjects.push(o)
  965.        o.visible=false
  966.      end
  967.   }
  968.   ObjectSpace.each_object(Window){|o|
  969.      if !o.disposed? && o.visible
  970.        visibleObjects.push(o)
  971.        o.visible=false
  972.      end
  973.   }
  974.   return visibleObjects
  975. end
  976.  
  977. def pbShowObjects(visibleObjects)
  978.   for o in visibleObjects
  979.     if !pbDisposed?(o)
  980.       o.visible=true
  981.     end
  982.   end
  983. end
  984.  
  985. def pbLoadRpgxpScene(scene)
  986.   return if !$scene.is_a?(Scene_Map)
  987.   oldscene=$scene
  988.   $scene=scene
  989.   Graphics.freeze
  990.   oldscene.disposeSpritesets
  991.   visibleObjects=pbHideVisibleObjects
  992.   Graphics.transition(15)
  993.   Graphics.freeze
  994.   while $scene && !$scene.is_a?(Scene_Map)
  995.     $scene.main
  996.   end
  997.   Graphics.transition(15)
  998.   Graphics.freeze
  999.   oldscene.createSpritesets
  1000.   pbShowObjects(visibleObjects)
  1001.   Graphics.transition(20)
  1002.   $scene=oldscene
  1003. end
  1004.  
  1005. # Gets the value of a variable.
  1006. def pbGet(id)
  1007.   return 0 if !id || !$game_variables
  1008.   return $game_variables[id]
  1009. end
  1010.  
  1011. # Sets the value of a variable.
  1012. def pbSet(id,value)
  1013.   if id && id>=0
  1014.     $game_variables[id]=value if $game_variables
  1015.     $game_map.need_refresh = true if $game_map
  1016.   end
  1017. end
  1018.  
  1019. # Runs a common event and waits until the common event is finished.
  1020. # Requires the script "PokemonMessages"
  1021. def pbCommonEvent(id)
  1022.   return false if id<0
  1023.   ce=$data_common_events[id]
  1024.   return false if !ce
  1025.   celist=ce.list
  1026.   interp=Interpreter.new
  1027.   interp.setup(celist,0)
  1028.   begin
  1029.     Graphics.update
  1030.     Input.update
  1031.     interp.update
  1032.     pbUpdateSceneMap
  1033.   end while interp.running?
  1034.   return true
  1035. end
  1036.  
  1037. def pbExclaim(event,id=EXCLAMATION_ANIMATION_ID,tinting=false)
  1038.   if event.is_a?(Array)
  1039.     sprite=nil
  1040.     done=[]
  1041.     for i in event
  1042.       if !done.include?(i.id)
  1043.         sprite=$scene.spriteset.addUserAnimation(id,i.x,i.y,tinting)
  1044.         done.push(i.id)
  1045.       end
  1046.     end
  1047.   else
  1048.     sprite=$scene.spriteset.addUserAnimation(id,event.x,event.y,tinting)
  1049.   end
  1050.   while !sprite.disposed?
  1051.     Graphics.update
  1052.     Input.update
  1053.     pbUpdateSceneMap
  1054.   end
  1055. end
  1056.  
  1057. def pbNoticePlayer(event)
  1058.   if !pbFacingEachOther(event,$game_player)
  1059.     pbExclaim(event)
  1060.   end
  1061.   pbTurnTowardEvent($game_player,event)
  1062.   Kernel.pbMoveTowardPlayer(event)
  1063. end
  1064.  
  1065.  
  1066.  
  1067. ################################################################################
  1068. # Loads Pokémon/item/trainer graphics
  1069. ################################################################################
  1070. def pbPokemonBitmapFile(species, shiny, back=false)   # Unused
  1071.   if shiny
  1072.     # Load shiny bitmap
  1073.     ret=sprintf("Graphics/Battlers/%ss%s",getConstantName(PBSpecies,species),back ? "b" : "") rescue nil
  1074.     if !pbResolveBitmap(ret)
  1075.       ret=sprintf("Graphics/Battlers/%03ds%s",species,back ? "b" : "")
  1076.     end
  1077.     return ret
  1078.   else
  1079.     # Load normal bitmap
  1080.     ret=sprintf("Graphics/Battlers/%s%s",getConstantName(PBSpecies,species),back ? "b" : "") rescue nil
  1081.     if !pbResolveBitmap(ret)
  1082.       ret=sprintf("Graphics/Battlers/%03d%s",species,back ? "b" : "")
  1083.     end
  1084.     return ret
  1085.   end
  1086. end
  1087.  
  1088. def pbLoadPokemonBitmap(pokemon, back=false,isMini=false)
  1089.   return pbLoadPokemonBitmapSpecies(pokemon,pokemon.species,back,isMini)
  1090. end
  1091.  
  1092. # Note: Returns an AnimatedBitmap, not a Bitmap
  1093. def pbLoadPokemonBitmapSpecies(pokemon, species, back=false,isMini=false)
  1094.   ret=nil
  1095.   if pokemon.isEgg?
  1096.     bitmapFileName=sprintf("Graphics/Battlers/%segg",getConstantName(PBSpecies,species)) rescue nil
  1097.     if !pbResolveBitmap(bitmapFileName)
  1098.       bitmapFileName=sprintf("Graphics/Battlers/%03degg",species)
  1099.       if !pbResolveBitmap(bitmapFileName)
  1100.         bitmapFileName=sprintf("Graphics/Battlers/egg")
  1101.       end
  1102.     end
  1103.     bitmapFileName=pbResolveBitmap(bitmapFileName)
  1104.   else
  1105.     bitmapFileName=pbCheckPokemonBitmapFiles([species,back,
  1106.                                               (pokemon.isFemale?),
  1107.                                               pokemon.isShiny?,
  1108.                                               (pokemon.form rescue 0),
  1109.                                               (pokemon.isShadow? rescue false)])
  1110.     # Alter bitmap if supported
  1111.     alterBitmap=(MultipleForms.getFunction(species,"alterBitmap") rescue nil)
  1112.   end
  1113.   if bitmapFileName && alterBitmap
  1114.     animatedBitmap=AnimatedBitmap.new(bitmapFileName)
  1115.     copiedBitmap=animatedBitmap.copy
  1116.     animatedBitmap.dispose
  1117.     copiedBitmap.each {|bitmap|
  1118.        alterBitmap.call(pokemon,bitmap)
  1119.     }
  1120.     ret=copiedBitmap
  1121.   elsif bitmapFileName
  1122.     ret=AnimatedBitmap.new(bitmapFileName)
  1123.   end
  1124.  
  1125.   if isMini
  1126.     species = ('%03d'%species).to_s
  1127.     species = species+"s" if pokemon.isShiny?
  1128.    
  1129.     form = pokemon.form.to_s rescue "0"
  1130.     if form == "0"
  1131.       form = ""
  1132.     end
  1133.    
  1134.     bitmapFileName="Graphics/Characters/"+species+"_"+form+".png";
  1135.     ret = AnimatedBitmap.new(bitmapFileName)
  1136.    
  1137.     cut = BitmapWrapper.new(ret.width/4,ret.height/4)
  1138.    
  1139.     if back
  1140.       yfactor = 2
  1141.       cut.blt(0,0,ret.bitmap,Rect.new(0,(ret.height/4)*yfactor,ret.width/4,ret.height/4))
  1142.     else
  1143.       yfactor = 1
  1144.       cut.blt(0,0,ret.bitmap,Rect.new(0,(ret.height/4)*yfactor,ret.width/4,ret.height/4))
  1145.     end
  1146.  
  1147.     ret.setBitmap(cut)
  1148.   end
  1149.  
  1150.   return ret
  1151. end
  1152.  
  1153. # Note: Returns an AnimatedBitmap, not a Bitmap
  1154. def pbLoadSpeciesBitmap(species,female=false,form=0,shiny=false,shadow=false,back=false,egg=false)
  1155.   ret=nil
  1156.   if egg
  1157.     bitmapFileName=sprintf("Graphics/Battlers/%segg",getConstantName(PBSpecies,species)) rescue nil
  1158.     if !pbResolveBitmap(bitmapFileName)
  1159.       bitmapFileName=sprintf("Graphics/Battlers/%03degg",species)
  1160.       if !pbResolveBitmap(bitmapFileName)
  1161.         bitmapFileName=sprintf("Graphics/Battlers/egg")
  1162.       end
  1163.     end
  1164.     bitmapFileName=pbResolveBitmap(bitmapFileName)
  1165.   else
  1166.     bitmapFileName=pbCheckPokemonBitmapFiles([species,back,female,shiny,form,shadow])
  1167.   end
  1168.   if bitmapFileName
  1169.     ret=AnimatedBitmap.new(bitmapFileName)
  1170.   end
  1171.   return ret
  1172. end
  1173.  
  1174. def pbCheckPokemonBitmapFiles(params)
  1175.   species=params[0]
  1176.   back=params[1]
  1177.   factors=[]
  1178.   factors.push([5,params[5],false]) if params[5] && params[5]!=false     # shadow
  1179.   factors.push([2,params[2],false]) if params[2] && params[2]!=false     # gender
  1180.   factors.push([3,params[3],false]) if params[3] && params[3]!=false     # shiny
  1181.   factors.push([4,params[4].to_s,""]) if params[4] && params[4].to_s!="" &&
  1182.                                                       params[4].to_s!="0" # form
  1183.   tshadow=false
  1184.   tgender=false
  1185.   tshiny=false
  1186.   tform=""
  1187.   for i in 0...2**factors.length
  1188.     for j in 0...factors.length
  1189.       case factors[j][0]
  1190.       when 2   # gender
  1191.         tgender=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
  1192.       when 3   # shiny
  1193.         tshiny=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
  1194.       when 4   # form
  1195.         tform=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
  1196.       when 5   # shadow
  1197.         tshadow=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
  1198.       end
  1199.     end
  1200.     bitmapFileName=sprintf("Graphics/Battlers/%s%s%s%s%s%s",
  1201.        getConstantName(PBSpecies,species),
  1202.        tgender ? "f" : "",
  1203.        tshiny ? "s" : "",
  1204.        back ? "b" : "",
  1205.        (tform!="" ? "_"+tform : ""),
  1206.        tshadow ? "_shadow" : "") rescue nil
  1207.     ret=pbResolveBitmap(bitmapFileName)
  1208.     return ret if ret
  1209.     bitmapFileName=sprintf("Graphics/Battlers/%03d%s%s%s%s%s",
  1210.        species,
  1211.        tgender ? "f" : "",
  1212.        tshiny ? "s" : "",
  1213.        back ? "b" : "",
  1214.        (tform!="" ? "_"+tform : ""),
  1215.        tshadow ? "_shadow" : "")
  1216.     ret=pbResolveBitmap(bitmapFileName)
  1217.     return ret if ret
  1218.   end
  1219.   return nil
  1220. end
  1221.  
  1222. def pbLoadPokemonIcon(pokemon)
  1223.   return AnimatedBitmap.new(pbPokemonIconFile(pokemon)).deanimate
  1224. end
  1225.  
  1226. def pbPokemonIconFile(pokemon)
  1227.   bitmapFileName=nil
  1228.   bitmapFileName=pbCheckPokemonIconFiles([pokemon.species,
  1229.                                           (pokemon.isFemale?),
  1230.                                           pokemon.isShiny?,
  1231.                                           (pokemon.form rescue 0),
  1232.                                           (pokemon.isShadow? rescue false)],
  1233.                                           pokemon.isEgg?)
  1234.   return bitmapFileName
  1235. end
  1236.  
  1237. def pbCheckPokemonIconFiles(params,egg=false)
  1238.   species=params[0]
  1239.   if egg
  1240.     bitmapFileName=sprintf("Graphics/Icons/icon%segg",getConstantName(PBSpecies,species)) rescue nil
  1241.     if !pbResolveBitmap(bitmapFileName)
  1242.       bitmapFileName=sprintf("Graphics/Icons/icon%03degg",species)
  1243.       if !pbResolveBitmap(bitmapFileName)
  1244.         bitmapFileName=sprintf("Graphics/Icons/iconEgg")
  1245.       end
  1246.     end
  1247.     return pbResolveBitmap(bitmapFileName)
  1248.   else
  1249.     factors=[]
  1250.     factors.push([4,params[4],false]) if params[4] && params[4]!=false     # shadow
  1251.     factors.push([1,params[1],false]) if params[1] && params[1]!=false     # gender
  1252.     factors.push([2,params[2],false]) if params[2] && params[2]!=false     # shiny
  1253.     factors.push([3,params[3].to_s,""]) if params[3] && params[3].to_s!="" &&
  1254.                                                         params[3].to_s!="0" # form
  1255.     tshadow=false
  1256.     tgender=false
  1257.     tshiny=false
  1258.     tform=""
  1259.     for i in 0...2**factors.length
  1260.       for j in 0...factors.length
  1261.         case factors[j][0]
  1262.         when 1   # gender
  1263.           tgender=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
  1264.         when 2   # shiny
  1265.           tshiny=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
  1266.         when 3   # form
  1267.           tform=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
  1268.         when 4   # shadow
  1269.           tshadow=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
  1270.         end
  1271.       end
  1272.       bitmapFileName=sprintf("Graphics/Icons/icon%s%s%s%s%s",
  1273.          getConstantName(PBSpecies,species),
  1274.          tgender ? "f" : "",
  1275.          tshiny ? "s" : "",
  1276.          (tform!="" ? "_"+tform : ""),
  1277.          tshadow ? "_shadow" : "") rescue nil
  1278.       ret=pbResolveBitmap(bitmapFileName)
  1279.       return ret if ret
  1280.       bitmapFileName=sprintf("Graphics/Icons/icon%03d%s%s%s%s",
  1281.          species,
  1282.          tgender ? "f" : "",
  1283.          tshiny ? "s" : "",
  1284.          (tform!="" ? "_"+tform : ""),
  1285.          tshadow ? "_shadow" : "")
  1286.       ret=pbResolveBitmap(bitmapFileName)
  1287.       return ret if ret
  1288.     end
  1289.   end
  1290.   return nil
  1291. end
  1292.  
  1293. def pbPokemonFootprintFile(pokemon)   # Used by the Pokédex
  1294.   return nil if !pokemon
  1295.   if pokemon.is_a?(Numeric)
  1296.     bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%s",getConstantName(PBSpecies,pokemon)) rescue nil
  1297.     bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%03d",pokemon) if !pbResolveBitmap(bitmapFileName)
  1298.   else
  1299.     bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%s_%d",getConstantName(PBSpecies,pokemon.species),(pokemon.form rescue 0)) rescue nil
  1300.     if !pbResolveBitmap(bitmapFileName)
  1301.       bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%03d_%d",pokemon.species,(pokemon.form rescue 0)) rescue nil
  1302.       if !pbResolveBitmap(bitmapFileName)
  1303.         bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%s",getConstantName(PBSpecies,pokemon.species)) rescue nil
  1304.         if !pbResolveBitmap(bitmapFileName)
  1305.           bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%03d",pokemon.species)
  1306.         end
  1307.       end
  1308.     end
  1309.   end
  1310.   return pbResolveBitmap(bitmapFileName)
  1311. end
  1312.  
  1313. def pbItemIconFile(item)
  1314.   return nil if !item
  1315.   bitmapFileName=nil
  1316.   if item==0
  1317.     bitmapFileName=sprintf("Graphics/Icons/itemBack")
  1318.   else
  1319.     bitmapFileName=sprintf("Graphics/Icons/item%s",getConstantName(PBItems,item)) rescue nil
  1320.     if !pbResolveBitmap(bitmapFileName)
  1321.       bitmapFileName=sprintf("Graphics/Icons/item%03d",item)
  1322.     end
  1323.   end
  1324.   return bitmapFileName
  1325. end
  1326.  
  1327. def pbMailBackFile(item)
  1328.   return nil if !item
  1329.   bitmapFileName=sprintf("Graphics/Pictures/mail%s",getConstantName(PBItems,item)) rescue nil
  1330.   if !pbResolveBitmap(bitmapFileName)
  1331.     bitmapFileName=sprintf("Graphics/Pictures/mail%03d",item)
  1332.   end
  1333.   return bitmapFileName
  1334. end
  1335.  
  1336. def pbTrainerCharFile(type)
  1337.   return nil if !type
  1338.   bitmapFileName=sprintf("Graphics/Characters/trchar%s",getConstantName(PBTrainers,type)) rescue nil
  1339.   if !pbResolveBitmap(bitmapFileName)
  1340.     bitmapFileName=sprintf("Graphics/Characters/trchar%03d",type)
  1341.   end
  1342.   return bitmapFileName
  1343. end
  1344.  
  1345. def pbTrainerCharNameFile(type)
  1346.   return nil if !type
  1347.   bitmapFileName=sprintf("trchar%s",getConstantName(PBTrainers,type)) rescue nil
  1348.   if !pbResolveBitmap(sprintf("Graphics/Characters/"+bitmapFileName))
  1349.     bitmapFileName=sprintf("trchar%03d",type)
  1350.   end
  1351.   return bitmapFileName
  1352. end
  1353.  
  1354. def pbTrainerHeadFile(type)
  1355.   return nil if !type
  1356.   bitmapFileName=sprintf("Graphics/Pictures/mapPlayer%s",getConstantName(PBTrainers,type)) rescue nil
  1357.   if !pbResolveBitmap(bitmapFileName)
  1358.     bitmapFileName=sprintf("Graphics/Pictures/mapPlayer%03d",type)
  1359.   end
  1360.   return bitmapFileName
  1361. end
  1362.  
  1363. def pbPlayerHeadFile(type)
  1364.   return nil if !type
  1365.   outfit=$Trainer ? $Trainer.outfit : 0
  1366.   bitmapFileName=sprintf("Graphics/Pictures/mapPlayer%s_%d",
  1367.      getConstantName(PBTrainers,type),outfit) rescue nil
  1368.   if !pbResolveBitmap(bitmapFileName)
  1369.     bitmapFileName=sprintf("Graphics/Pictures/mapPlayer%03d_%d",type,outfit)
  1370.     if !pbResolveBitmap(bitmapFileName)
  1371.       bitmapFileName=pbTrainerHeadFile(type)
  1372.     end
  1373.   end
  1374.   return bitmapFileName
  1375. end
  1376.  
  1377. def pbTrainerSpriteFile(type)
  1378.   return nil if !type
  1379.   bitmapFileName=sprintf("Graphics/Characters/trainer%s",getConstantName(PBTrainers,type)) rescue nil
  1380.   if !pbResolveBitmap(bitmapFileName)
  1381.     bitmapFileName=sprintf("Graphics/Characters/trainer%03d",type)
  1382.   end
  1383.   return bitmapFileName
  1384. end
  1385.  
  1386. def pbTrainerSpriteBackFile(type)
  1387.   return nil if !type
  1388.   bitmapFileName=sprintf("Graphics/Characters/trback%s",getConstantName(PBTrainers,type)) rescue nil
  1389.   if !pbResolveBitmap(bitmapFileName)
  1390.     bitmapFileName=sprintf("Graphics/Characters/trback%03d",type)
  1391.   end
  1392.   return bitmapFileName
  1393. end
  1394.  
  1395. def pbPlayerSpriteFile(type)
  1396.   return nil if !type
  1397.   outfit=$Trainer ? $Trainer.outfit : 0
  1398.   bitmapFileName=sprintf("Graphics/Characters/trainer%s_%d",
  1399.      getConstantName(PBTrainers,type),outfit) rescue nil
  1400.   if !pbResolveBitmap(bitmapFileName)
  1401.     bitmapFileName=sprintf("Graphics/Characters/trainer%03d_%d",type,outfit)
  1402.     if !pbResolveBitmap(bitmapFileName)
  1403.       bitmapFileName=pbTrainerSpriteFile(type)
  1404.     end
  1405.   end
  1406.   return bitmapFileName
  1407. end
  1408.  
  1409. def pbPlayerSpriteBackFile(type)
  1410.   return nil if !type
  1411.   outfit=$Trainer ? $Trainer.outfit : 0
  1412.   bitmapFileName=sprintf("Graphics/Characters/trback%s_%d",
  1413.      getConstantName(PBTrainers,type),outfit) rescue nil
  1414.   if !pbResolveBitmap(bitmapFileName)
  1415.     bitmapFileName=sprintf("Graphics/Characters/trback%03d_%d",type,outfit)
  1416.     if !pbResolveBitmap(bitmapFileName)
  1417.       bitmapFileName=pbTrainerSpriteBackFile(type)
  1418.     end
  1419.   end
  1420.   return bitmapFileName
  1421. end
  1422.  
  1423.  
  1424.  
  1425. ################################################################################
  1426. # Loads music and sound effects
  1427. ################################################################################
  1428. def pbResolveAudioSE(file)
  1429.   return nil if !file
  1430.   if RTP.exists?("Audio/SE/"+file,["",".wav",".mp3",".ogg"])
  1431.     return RTP.getPath("Audio/SE/"+file,["",".wav",".mp3",".ogg"])
  1432.   end
  1433.   return nil
  1434. end
  1435.  
  1436. def pbCryFrameLength(pokemon,pitch=nil)
  1437.   return 0 if !pokemon
  1438.   pitch=100 if !pitch
  1439.   pitch=pitch.to_f/100
  1440.   return 0 if pitch<=0
  1441.   playtime=0.0
  1442.   if pokemon.is_a?(Numeric)
  1443.     pkmnwav=pbResolveAudioSE(pbCryFile(pokemon))
  1444.     playtime=getPlayTime(pkmnwav) if pkmnwav
  1445.   elsif !pokemon.isEgg?
  1446.     if pokemon.respond_to?("chatter") && pokemon.chatter
  1447.       playtime=pokemon.chatter.time
  1448.       pitch=1.0
  1449.     else
  1450.       pkmnwav=pbResolveAudioSE(pbCryFile(pokemon))
  1451.       playtime=getPlayTime(pkmnwav) if pkmnwav
  1452.     end
  1453.   end
  1454.   playtime/=pitch # sound is lengthened the lower the pitch
  1455.   # 4 is added to provide a buffer between sounds
  1456.   return (playtime*Graphics.frame_rate).ceil+4
  1457. end
  1458.  
  1459. def pbPlayCry(pokemon,volume=90,pitch=nil)
  1460.   return if !pokemon
  1461.   if pokemon.is_a?(Numeric)
  1462.     pkmnwav=pbCryFile(pokemon)
  1463.     if pkmnwav
  1464.       pbSEPlay(RPG::AudioFile.new(pkmnwav,volume,pitch ? pitch : 100)) rescue nil
  1465.     end
  1466.   elsif !pokemon.isEgg?
  1467.     if pokemon.respond_to?("chatter") && pokemon.chatter
  1468.       pokemon.chatter.play
  1469.     else
  1470.       pkmnwav=pbCryFile(pokemon)
  1471.       if pkmnwav
  1472.         pbSEPlay(RPG::AudioFile.new(pkmnwav,volume,
  1473.            pitch ? pitch : (pokemon.hp*25/pokemon.totalhp)+75)) rescue nil
  1474.       end
  1475.     end
  1476.   end
  1477. end
  1478.  
  1479. def pbCryFile(pokemon)
  1480.   return nil if !pokemon
  1481.   if pokemon.is_a?(Numeric)
  1482.     filename=sprintf("Cries/%sCry",getConstantName(PBSpecies,pokemon)) rescue nil
  1483.     filename=sprintf("Cries/%03dCry",pokemon) if !pbResolveAudioSE(filename)
  1484.     return filename if pbResolveAudioSE(filename)
  1485.   elsif !pokemon.isEgg?
  1486.     filename=sprintf("Cries/%sCry_%d",getConstantName(PBSpecies,pokemon.species),(pokemon.form rescue 0)) rescue nil
  1487.     filename=sprintf("Cries/%03dCry_%d",pokemon.species,(pokemon.form rescue 0)) if !pbResolveAudioSE(filename)
  1488.     if !pbResolveAudioSE(filename)
  1489.       filename=sprintf("Cries/%sCry",getConstantName(PBSpecies,pokemon.species)) rescue nil
  1490.     end
  1491.     filename=sprintf("Cries/%03dCry",pokemon.species) if !pbResolveAudioSE(filename)
  1492.     return filename if pbResolveAudioSE(filename)
  1493.   end
  1494.   return nil
  1495. end
  1496.  
  1497. def pbGetWildBattleBGM(species)
  1498.   if $PokemonGlobal.nextBattleBGM
  1499.     return $PokemonGlobal.nextBattleBGM.clone
  1500.   end
  1501.   ret=nil
  1502.   if !ret && $game_map
  1503.     # Check map-specific metadata
  1504.     music=pbGetMetadata($game_map.map_id,MetadataMapWildBattleBGM)
  1505.     if music && music!=""
  1506.       ret=pbStringToAudioFile(music)
  1507.     end
  1508.   end
  1509.   if !ret
  1510.     # Check global metadata
  1511.     music=pbGetMetadata(0,MetadataWildBattleBGM)
  1512.     if music && music!=""
  1513.       ret=pbStringToAudioFile(music)
  1514.     end
  1515.   end
  1516.   ret=pbStringToAudioFile("002-Battle02") if !ret
  1517.   return ret
  1518. end
  1519.  
  1520. def pbGetWildVictoryME
  1521.   if $PokemonGlobal.nextBattleME
  1522.     return $PokemonGlobal.nextBattleME.clone
  1523.   end
  1524.   ret=nil
  1525.   if !ret && $game_map
  1526.     # Check map-specific metadata
  1527.     music=pbGetMetadata($game_map.map_id,MetadataMapWildVictoryME)
  1528.     if music && music!=""
  1529.       ret=pbStringToAudioFile(music)
  1530.     end
  1531.   end
  1532.   if !ret
  1533.     # Check global metadata
  1534.     music=pbGetMetadata(0,MetadataWildVictoryME)
  1535.     if music && music!=""
  1536.       ret=pbStringToAudioFile(music)
  1537.     end
  1538.   end
  1539.   ret=pbStringToAudioFile("001-Victory01") if !ret
  1540.   ret.name="../../Audio/ME/"+ret.name
  1541.   return ret
  1542. end
  1543.  
  1544. def pbPlayTrainerIntroME(trainertype)
  1545.   pbRgssOpen("Data/trainertypes.dat","rb"){|f|
  1546.      trainertypes=Marshal.load(f)
  1547.      if trainertypes[trainertype]
  1548.        bgm=trainertypes[trainertype][6]
  1549.        if bgm && bgm!=""
  1550.          bgm=pbStringToAudioFile(bgm)
  1551.          pbMEPlay(bgm)
  1552.          return
  1553.        end
  1554.      end
  1555.   }
  1556. end
  1557.  
  1558. def pbGetTrainerBattleBGM(trainer) # can be a PokeBattle_Trainer or an array of PokeBattle_Trainer
  1559.   if $PokemonGlobal.nextBattleBGM
  1560.     return $PokemonGlobal.nextBattleBGM.clone
  1561.   end
  1562.   music=nil
  1563.   pbRgssOpen("Data/trainertypes.dat","rb"){|f|
  1564.      trainertypes=Marshal.load(f)
  1565.      if !trainer.is_a?(Array)
  1566.        trainerarray=[trainer]
  1567.      else
  1568.        trainerarray=trainer
  1569.      end
  1570.      for i in 0...trainerarray.length
  1571.        trainertype=trainerarray[i].trainertype
  1572.        if trainertypes[trainertype]
  1573.          music=trainertypes[trainertype][4]
  1574.        end
  1575.      end
  1576.   }
  1577.   ret=nil
  1578.   if music && music!=""
  1579.     ret=pbStringToAudioFile(music)
  1580.   end
  1581.   if !ret && $game_map
  1582.     # Check map-specific metadata
  1583.     music=pbGetMetadata($game_map.map_id,MetadataMapTrainerBattleBGM)
  1584.     if music && music!=""
  1585.       ret=pbStringToAudioFile(music)
  1586.     end
  1587.   end
  1588.   if !ret
  1589.     # Check global metadata
  1590.     music=pbGetMetadata(0,MetadataTrainerBattleBGM)
  1591.     if music && music!=""
  1592.       ret=pbStringToAudioFile(music)
  1593.     end
  1594.   end
  1595.   ret=pbStringToAudioFile("005-Boss01") if !ret
  1596.   return ret
  1597. end
  1598.  
  1599. def pbGetTrainerBattleBGMFromType(trainertype)
  1600.   if $PokemonGlobal.nextBattleBGM
  1601.     return $PokemonGlobal.nextBattleBGM.clone
  1602.   end
  1603.   music=nil
  1604.   pbRgssOpen("Data/trainertypes.dat","rb"){|f|
  1605.     trainertypes=Marshal.load(f)
  1606.     if trainertypes[trainertype]
  1607.       music=trainertypes[trainertype][4]
  1608.     end
  1609.   }
  1610.   ret=nil
  1611.   if music && music!=""
  1612.     ret=pbStringToAudioFile(music)
  1613.   end
  1614.   if !ret && $game_map
  1615.     # Check map-specific metadata
  1616.     music=pbGetMetadata($game_map.map_id,MetadataMapTrainerBattleBGM)
  1617.     if music && music!=""
  1618.       ret=pbStringToAudioFile(music)
  1619.     end
  1620.   end
  1621.   if !ret
  1622.     # Check global metadata
  1623.     music=pbGetMetadata(0,MetadataTrainerBattleBGM)
  1624.     if music && music!=""
  1625.       ret=pbStringToAudioFile(music)
  1626.     end
  1627.   end
  1628.   ret=pbStringToAudioFile("005-Boss01") if !ret
  1629.   return ret
  1630. end
  1631.  
  1632. def pbGetTrainerVictoryME(trainer) # can be a PokeBattle_Trainer or an array of PokeBattle_Trainer
  1633.   if $PokemonGlobal.nextBattleME
  1634.     return $PokemonGlobal.nextBattleME.clone
  1635.   end
  1636.   music=nil
  1637.   pbRgssOpen("Data/trainertypes.dat","rb"){|f|
  1638.      trainertypes=Marshal.load(f)
  1639.      if !trainer.is_a?(Array)
  1640.        trainerarray=[trainer]
  1641.      else
  1642.        trainerarray=trainer
  1643.      end
  1644.      for i in 0...trainerarray.length
  1645.        trainertype=trainerarray[i].trainertype
  1646.        if trainertypes[trainertype]
  1647.          music=trainertypes[trainertype][5]
  1648.        end
  1649.      end
  1650.   }
  1651.   ret=nil
  1652.   if music && music!=""
  1653.     ret=pbStringToAudioFile(music)
  1654.   end
  1655.   if !ret && $game_map
  1656.     # Check map-specific metadata
  1657.     music=pbGetMetadata($game_map.map_id,MetadataMapTrainerVictoryME)
  1658.     if music && music!=""
  1659.       ret=pbStringToAudioFile(music)
  1660.     end
  1661.   end
  1662.   if !ret
  1663.     # Check global metadata
  1664.     music=pbGetMetadata(0,MetadataTrainerVictoryME)
  1665.     if music && music!=""
  1666.       ret=pbStringToAudioFile(music)
  1667.     end
  1668.   end
  1669.   ret=pbStringToAudioFile("001-Victory01") if !ret
  1670.   ret.name="../../Audio/ME/"+ret.name
  1671.   return ret
  1672. end
  1673.  
  1674.  
  1675.  
  1676. ################################################################################
  1677. # Creating and storing Pokémon
  1678. ################################################################################
  1679. # For demonstration purposes only, not to be used in a real game.
  1680. def pbCreatePokemon
  1681.   party=[]
  1682.   species=[:PIKACHU,:PIDGEOTTO,:KADABRA,:GYARADOS,:DIGLETT,:CHANSEY]
  1683.   for id in species
  1684.     party.push(getConst(PBSpecies,id)) if hasConst?(PBSpecies,id)
  1685.   end
  1686.   # Species IDs of the Pokémon to be created
  1687.   for i in 0...party.length
  1688.     species=party[i]
  1689.     # Generate Pokémon with species and level 20
  1690.     $Trainer.party[i]=PokeBattle_Pokemon.new(species,20,$Trainer)
  1691.     $Trainer.seen[species]=true # Set this species to seen and owned
  1692.     $Trainer.owned[species]=true
  1693.     pbSeenForm($Trainer.party[i])
  1694.   end
  1695.   $Trainer.party[1].pbLearnMove(:FLY)
  1696.   $Trainer.party[2].pbLearnMove(:FLASH)
  1697.   $Trainer.party[2].pbLearnMove(:TELEPORT)
  1698.   $Trainer.party[3].pbLearnMove(:SURF)
  1699.   $Trainer.party[3].pbLearnMove(:DIVE)
  1700.   $Trainer.party[3].pbLearnMove(:WATERFALL)
  1701.   $Trainer.party[4].pbLearnMove(:DIG)
  1702.   $Trainer.party[4].pbLearnMove(:CUT)
  1703.   $Trainer.party[4].pbLearnMove(:HEADBUTT)
  1704.   $Trainer.party[4].pbLearnMove(:ROCKSMASH)
  1705.   $Trainer.party[5].pbLearnMove(:SOFTBOILED)
  1706.   $Trainer.party[5].pbLearnMove(:STRENGTH)
  1707.   $Trainer.party[5].pbLearnMove(:SWEETSCENT)
  1708.   for i in 0...party.length
  1709.     $Trainer.party[i].pbRecordFirstMoves
  1710.   end
  1711. end
  1712.  
  1713. def pbBoxesFull?
  1714.   return !$Trainer || ($Trainer.party.length==6 && $PokemonStorage.full?)
  1715. end
  1716.  
  1717. def pbNickname(pokemon)
  1718.   speciesname=PBSpecies.getName(pokemon.species)
  1719.   if Kernel.pbConfirmMessage(_INTL("Would you like to give a nickname to {1}?",speciesname))
  1720.     helptext=_INTL("{1}'s nickname?",speciesname)
  1721.     newname=pbEnterPokemonName(helptext,0,10,"",pokemon)
  1722.     pokemon.name=newname if newname!=""
  1723.   end
  1724. end
  1725.  
  1726. def pbStorePokemon(pokemon)
  1727.   if pbBoxesFull?
  1728.     Kernel.pbMessage(_INTL("There's no more room for Pokémon!\1"))
  1729.     Kernel.pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
  1730.     return
  1731.   end
  1732.   pokemon.pbRecordFirstMoves
  1733.   if $Trainer.party.length<6
  1734.     $Trainer.party[$Trainer.party.length]=pokemon
  1735.   else
  1736.     oldcurbox=$PokemonStorage.currentBox
  1737.     storedbox=$PokemonStorage.pbStoreCaught(pokemon)
  1738.     curboxname=$PokemonStorage[oldcurbox].name
  1739.     boxname=$PokemonStorage[storedbox].name
  1740.     creator=nil
  1741.     creator=Kernel.pbGetStorageCreator if $PokemonGlobal.seenStorageCreator
  1742.     if storedbox!=oldcurbox
  1743.       if creator
  1744.         Kernel.pbMessage(_INTL("Box \"{1}\" on {2}'s PC was full.\1",curboxname,creator))
  1745.       else
  1746.         Kernel.pbMessage(_INTL("Box \"{1}\" on someone's PC was full.\1",curboxname))
  1747.       end
  1748.       Kernel.pbMessage(_INTL("{1} was transferred to box \"{2}.\"",pokemon.name,boxname))
  1749.     else
  1750.       if creator
  1751.         Kernel.pbMessage(_INTL("{1} was transferred to {2}'s PC.\1",pokemon.name,creator))
  1752.       else
  1753.         Kernel.pbMessage(_INTL("{1} was transferred to someone's PC.\1",pokemon.name))
  1754.       end
  1755.       Kernel.pbMessage(_INTL("It was stored in box \"{1}.\"",boxname))
  1756.     end
  1757.   end
  1758. end
  1759.  
  1760. def pbNicknameAndStore(pokemon)
  1761.   if pbBoxesFull?
  1762.     Kernel.pbMessage(_INTL("There's no more room for Pokémon!\1"))
  1763.     Kernel.pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
  1764.     return
  1765.   end
  1766.   $Trainer.seen[pokemon.species]=true
  1767.   $Trainer.owned[pokemon.species]=true
  1768.   pbNickname(pokemon)
  1769.   pbStorePokemon(pokemon)
  1770. end
  1771.  
  1772. def pbAddPokemon(pokemon,level=nil,seeform=true)
  1773.   return if !pokemon || !$Trainer
  1774.   if pbBoxesFull?
  1775.     Kernel.pbMessage(_INTL("There's no more room for Pokémon!\1"))
  1776.     Kernel.pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
  1777.     return false
  1778.   end
  1779.   if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
  1780.     pokemon=getID(PBSpecies,pokemon)
  1781.   end
  1782.   if pokemon.is_a?(Integer) && level.is_a?(Integer)
  1783.     pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
  1784.   end
  1785.   speciesname=PBSpecies.getName(pokemon.species)
  1786.   Kernel.pbMessage(_INTL("{1} obtained {2}!\\se[PokemonGet]\1",$Trainer.name,speciesname))
  1787.   pbNicknameAndStore(pokemon)
  1788.   pbSeenForm(pokemon) if seeform
  1789.   return true
  1790. end
  1791.  
  1792. def pbAddPokemonSilent(pokemon,level=nil,seeform=true)
  1793.   return false if !pokemon || pbBoxesFull? || !$Trainer
  1794.   if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
  1795.     pokemon=getID(PBSpecies,pokemon)
  1796.   end
  1797.   if pokemon.is_a?(Integer) && level.is_a?(Integer)
  1798.     pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
  1799.   end
  1800.   $Trainer.seen[pokemon.species]=true
  1801.   $Trainer.owned[pokemon.species]=true
  1802.   pbSeenForm(pokemon) if seeform
  1803.   pokemon.pbRecordFirstMoves
  1804.   if $Trainer.party.length<6
  1805.     $Trainer.party[$Trainer.party.length]=pokemon
  1806.   else
  1807.     $PokemonStorage.pbStoreCaught(pokemon)
  1808.   end
  1809.   return true
  1810. end
  1811.  
  1812. def pbAddToParty(pokemon,level=nil,seeform=true)
  1813.   return false if !pokemon || !$Trainer || $Trainer.party.length>=6
  1814.   if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
  1815.     pokemon=getID(PBSpecies,pokemon)
  1816.   end
  1817.   if pokemon.is_a?(Integer) && level.is_a?(Integer)
  1818.     pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
  1819.   end
  1820.   speciesname=PBSpecies.getName(pokemon.species)
  1821.   Kernel.pbMessage(_INTL("{1} obtained {2}!\\se[PokemonGet]\1",$Trainer.name,speciesname))
  1822.   pbNicknameAndStore(pokemon)
  1823.   pbSeenForm(pokemon) if seeform
  1824.   return true
  1825. end
  1826.  
  1827. def pbAddToPartySilent(pokemon,level=nil,seeform=true)
  1828.   return false if !pokemon || !$Trainer || $Trainer.party.length>=6
  1829.   if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
  1830.     pokemon=getID(PBSpecies,pokemon)
  1831.   end
  1832.   if pokemon.is_a?(Integer) && level.is_a?(Integer)
  1833.     pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
  1834.   end
  1835.   $Trainer.seen[pokemon.species]=true
  1836.   $Trainer.owned[pokemon.species]=true
  1837.   pbSeenForm(pokemon) if seeform
  1838.   pokemon.pbRecordFirstMoves
  1839.   $Trainer.party[$Trainer.party.length]=pokemon
  1840.   return true
  1841. end
  1842.  
  1843. def pbAddForeignPokemon(pokemon,level=nil,ownerName=nil,nickname=nil,ownerGender=0,seeform=true)
  1844.   return false if !pokemon || !$Trainer || $Trainer.party.length>=6
  1845.   if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
  1846.     pokemon=getID(PBSpecies,pokemon)
  1847.   end
  1848.   if pokemon.is_a?(Integer) && level.is_a?(Integer)
  1849.     pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
  1850.   end
  1851.   # Set original trainer to a foreign one (if ID isn't already foreign)
  1852.   if pokemon.trainerID==$Trainer.id
  1853.     pokemon.trainerID=$Trainer.getForeignID
  1854.     pokemon.ot=ownerName if ownerName && ownerName!=""
  1855.     pokemon.otgender=ownerGender
  1856.   end
  1857.   # Set nickname
  1858.   pokemon.name=nickname[0,10] if nickname && nickname!=""
  1859.   # Recalculate stats
  1860.   pokemon.calcStats
  1861.   if ownerName
  1862.     Kernel.pbMessage(_INTL("{1} received a Pokémon from {2}.\\se[PokemonGet]\1",$Trainer.name,ownerName))
  1863.   else
  1864.     Kernel.pbMessage(_INTL("{1} received a Pokémon.\\se[PokemonGet]\1",$Trainer.name))
  1865.   end
  1866.   pbStorePokemon(pokemon)
  1867.   $Trainer.seen[pokemon.species]=true
  1868.   $Trainer.owned[pokemon.species]=true
  1869.   pbSeenForm(pokemon) if seeform
  1870.   return true
  1871. end
  1872.  
  1873. def pbGenerateEgg(pokemon,text="")
  1874.   return false if !pokemon || !$Trainer || $Trainer.party.length>=6
  1875.   if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
  1876.     pokemon=getID(PBSpecies,pokemon)
  1877.   end
  1878.   if pokemon.is_a?(Integer)
  1879.     pokemon=PokeBattle_Pokemon.new(pokemon,EGGINITIALLEVEL,$Trainer)
  1880.   end
  1881.   # Get egg steps
  1882.   dexdata=pbOpenDexData
  1883.   pbDexDataOffset(dexdata,pokemon.species,21)
  1884.   eggsteps=dexdata.fgetw
  1885.   dexdata.close
  1886.   # Set egg's details
  1887.   pokemon.name=_INTL("Egg")
  1888.   pokemon.eggsteps=eggsteps
  1889.   pokemon.obtainText=text
  1890.   pokemon.calcStats
  1891.   # Add egg to party
  1892.   $Trainer.party[$Trainer.party.length]=pokemon
  1893.   return true
  1894. end
  1895.  
  1896. def pbRemovePokemonAt(index)
  1897.   return false if index<0 || !$Trainer || index>=$Trainer.party.length
  1898.   haveAble=false
  1899.   for i in 0...$Trainer.party.length
  1900.     next if i==index
  1901.     haveAble=true if $Trainer.party[i].hp>0 && !$Trainer.party[i].isEgg?
  1902.   end
  1903.   return false if !haveAble
  1904.   $Trainer.party.delete_at(index)
  1905.   return true
  1906. end
  1907.  
  1908. def pbSeenForm(poke,gender=0,form=0)
  1909.   $Trainer.formseen=[] if !$Trainer.formseen
  1910.   $Trainer.formlastseen=[] if !$Trainer.formlastseen
  1911.   if poke.is_a?(String) || poke.is_a?(Symbol)
  1912.     poke=getID(PBSpecies,poke)
  1913.   end
  1914.   if poke.is_a?(PokeBattle_Pokemon)
  1915.     gender=poke.gender
  1916.     form=(poke.form rescue 0)
  1917.     species=poke.species
  1918.   else
  1919.     species=poke
  1920.   end
  1921.   return if !species || species<=0
  1922.   gender=0 if gender>1
  1923.   formnames=pbGetMessage(MessageTypes::FormNames,species)
  1924.   form=0 if !formnames || formnames==""
  1925.   $Trainer.formseen[species]=[[],[]] if !$Trainer.formseen[species]
  1926.   $Trainer.formseen[species][gender][form]=true
  1927.   $Trainer.formlastseen[species]=[] if !$Trainer.formlastseen[species]
  1928.   $Trainer.formlastseen[species]=[gender,form] if $Trainer.formlastseen[species]==[]
  1929. end
  1930.  
  1931.  
  1932.  
  1933. ################################################################################
  1934. # Analysing Pokémon
  1935. ################################################################################
  1936. # Heals all Pokémon in the party.
  1937. def pbHealAll
  1938.   return if !$Trainer
  1939.   for i in $Trainer.party
  1940.     i.heal
  1941.   end
  1942. end
  1943.  
  1944. # Returns the first unfainted, non-egg Pokémon in the player's party.
  1945. def pbFirstAblePokemon(variableNumber)
  1946.   for i in 0...$Trainer.party.length
  1947.     p=$Trainer.party[i]
  1948.     if p && !p.isEgg? && p.hp>0
  1949.       pbSet(variableNumber,i)
  1950.       return $Trainer.party[i]
  1951.     end
  1952.   end
  1953.   pbSet(variableNumber,-1)
  1954.   return nil
  1955. end
  1956.  
  1957. # Checks whether the player would still have an unfainted Pokémon if the
  1958. # Pokémon given by _pokemonIndex_ were removed from the party.
  1959. def pbCheckAble(pokemonIndex)
  1960.   for i in 0...$Trainer.party.length
  1961.     p=$Trainer.party[i]
  1962.     next if i==pokemonIndex
  1963.     return true if p && !p.isEgg? && p.hp>0
  1964.   end
  1965.   return false
  1966. end
  1967.  
  1968. # Returns true if there are no usable Pokémon in the player's party.
  1969. def pbAllFainted
  1970.   for i in $Trainer.party
  1971.     return false if !i.isEgg? && i.hp>0
  1972.   end
  1973.   return true
  1974. end
  1975.  
  1976. def pbBalancedLevel(party)
  1977.   return 1 if party.length==0
  1978.   # Calculate the mean of all levels
  1979.   sum=0
  1980.   party.each{|p| sum+=p.level }
  1981.   return 1 if sum==0
  1982.   average=sum.to_f/party.length.to_f
  1983.   # Calculate the standard deviation
  1984.   varianceTimesN=0
  1985.   for i in 0...party.length
  1986.     deviation=party[i].level-average
  1987.     varianceTimesN+=deviation*deviation
  1988.   end
  1989.   # Note: This is the "population" standard deviation calculation, since no
  1990.   # sample is being taken
  1991.   stdev=Math.sqrt(varianceTimesN/party.length)
  1992.   mean=0
  1993.   weights=[]
  1994.   # Skew weights according to standard deviation
  1995.   for i in 0...party.length
  1996.     weight=party[i].level.to_f/sum.to_f
  1997.     if weight<0.5
  1998.       weight-=(stdev/PBExperience::MAXLEVEL.to_f)
  1999.       weight=0.001 if weight<=0.001
  2000.     else
  2001.       weight+=(stdev/PBExperience::MAXLEVEL.to_f)
  2002.       weight=0.999 if weight>=0.999
  2003.     end
  2004.     weights.push(weight)
  2005.   end
  2006.   weightSum=0
  2007.   weights.each{|weight| weightSum+=weight }
  2008.   # Calculate the weighted mean, assigning each weight to each level's
  2009.   # contribution to the sum
  2010.   for i in 0...party.length
  2011.     mean+=party[i].level*weights[i]
  2012.   end
  2013.   mean/=weightSum
  2014.   # Round to nearest number
  2015.   mean=mean.round
  2016.   # Adjust level to minimum
  2017.   mean=1 if mean<1
  2018.   # Add 2 to the mean to challenge the player
  2019.   mean+=2
  2020.   # Adjust level to maximum
  2021.   mean=PBExperience::MAXLEVEL if mean>PBExperience::MAXLEVEL
  2022.   return mean
  2023. end
  2024.  
  2025. # Returns the Pokémon's size in millimeters.
  2026. def pbSize(pokemon)
  2027.   dexdata=pbOpenDexData
  2028.   pbDexDataOffset(dexdata,pokemon.species,33)
  2029.   baseheight=dexdata.fgetw # Gets the base height in tenths of a meter
  2030.   dexdata.close
  2031.   hpiv=pokemon.iv[0]&15
  2032.   ativ=pokemon.iv[1]&15
  2033.   dfiv=pokemon.iv[2]&15
  2034.   spiv=pokemon.iv[3]&15
  2035.   saiv=pokemon.iv[4]&15
  2036.   sdiv=pokemon.iv[5]&15
  2037.   m=pokemon.personalID&0xFF
  2038.   n=(pokemon.personalID>>8)&0xFF
  2039.   s=(((ativ^dfiv)*hpiv)^m)*256+(((saiv^sdiv)*spiv)^n)
  2040.   xyz=[]
  2041.   if s<10
  2042.     xyz=[290,1,0]
  2043.   elsif s<110
  2044.     xyz=[300,1,10]
  2045.   elsif s<310
  2046.     xyz=[400,2,110]
  2047.   elsif s<710
  2048.     xyz=[500,4,310]
  2049.   elsif s<2710
  2050.     xyz=[600,20,710]
  2051.   elsif s<7710
  2052.     xyz=[700,50,2710]
  2053.   elsif s<17710
  2054.     xyz=[800,100,7710]
  2055.   elsif s<32710
  2056.     xyz=[900,150,17710]
  2057.   elsif s<47710
  2058.     xyz=[1000,150,32710]
  2059.   elsif s<57710
  2060.     xyz=[1100,100,47710]
  2061.   elsif s<62710
  2062.     xyz=[1200,50,57710]
  2063.   elsif s<64710
  2064.     xyz=[1300,20,62710]
  2065.   elsif s<65210
  2066.     xyz=[1400,5,64710]
  2067.   elsif s<65410
  2068.     xyz=[1500,2,65210]
  2069.   else
  2070.     xyz=[1700,1,65510]
  2071.   end
  2072.   return (((s-xyz[2])/xyz[1]+xyz[0]).floor*baseheight/10).floor
  2073. end
  2074.  
  2075. # Returns true if the given species can be legitimately obtained as an egg.
  2076. def pbHasEgg?(species)
  2077.   if species.is_a?(String) || species.is_a?(Symbol)
  2078.     species=getID(PBSpecies,species)
  2079.   end
  2080.   evospecies=pbGetEvolvedFormData(species)
  2081.   compatspecies=(evospecies && evospecies[0]) ? evospecies[0][2] : species
  2082.   dexdata=pbOpenDexData
  2083.   pbDexDataOffset(dexdata,compatspecies,31)
  2084.   compat1=dexdata.fgetb   # Get egg group 1 of this species
  2085.   compat2=dexdata.fgetb   # Get egg group 2 of this species
  2086.   dexdata.close
  2087.   return false if isConst?(compat1,PBEggGroups,:Ditto) ||
  2088.                   isConst?(compat1,PBEggGroups,:Undiscovered) ||
  2089.                   isConst?(compat2,PBEggGroups,:Ditto) ||
  2090.                   isConst?(compat2,PBEggGroups,:Undiscovered)
  2091.   baby=pbGetBabySpecies(species)
  2092.   return true if species==baby   # Is a basic species
  2093.   baby=pbGetBabySpecies(species,0,0)
  2094.   return true if species==baby   # Is an egg species without incense
  2095.   return false
  2096. end
  2097.  
  2098.  
  2099.  
  2100. ################################################################################
  2101. # Look through Pokémon in storage, choose a Pokémon in the party
  2102. ################################################################################
  2103. # Yields every Pokémon/egg in storage in turn.
  2104. def pbEachPokemon
  2105.   for i in -1...$PokemonStorage.maxBoxes
  2106.     for j in 0...$PokemonStorage.maxPokemon(i)
  2107.       poke=$PokemonStorage[i][j]
  2108.       yield(poke,i) if poke
  2109.     end
  2110.   end
  2111. end
  2112.  
  2113. # Yields every Pokémon in storage in turn.
  2114. def pbEachNonEggPokemon
  2115.   pbEachPokemon{|pokemon,box|
  2116.      yield(pokemon,box) if !pokemon.isEgg?
  2117.   }
  2118. end
  2119.  
  2120. # Choose a Pokémon/egg from the party.
  2121. # Stores result in variable _variableNumber_ and the chosen Pokémon's name in
  2122. # variable _nameVarNumber_; result is -1 if no Pokémon was chosen
  2123. def pbChoosePokemon(variableNumber,nameVarNumber,ableProc=nil, allowIneligible=false)
  2124.   chosen=0
  2125.   pbFadeOutIn(99999){
  2126.      scene=PokemonScreen_Scene.new
  2127.      screen=PokemonScreen.new(scene,$Trainer.party)
  2128.      if ableProc
  2129.        chosen=screen.pbChooseAblePokemon(ableProc,allowIneligible)      
  2130.      else
  2131.        screen.pbStartScene(_INTL("Choose a Pokémon."),false)
  2132.        chosen=screen.pbChoosePokemon
  2133.        screen.pbEndScene
  2134.      end
  2135.   }
  2136.   pbSet(variableNumber,chosen)
  2137.   if chosen>=0
  2138.     pbSet(nameVarNumber,$Trainer.party[chosen].name)
  2139.   else
  2140.     pbSet(nameVarNumber,"")
  2141.   end
  2142. end
  2143.  
  2144. def pbChooseNonEggPokemon(variableNumber,nameVarNumber)
  2145.   pbChoosePokemon(variableNumber,nameVarNumber,proc {|poke|
  2146.      !poke.isEgg?
  2147.   })
  2148. end
  2149.  
  2150. def pbChooseAblePokemon(variableNumber,nameVarNumber)
  2151.   pbChoosePokemon(variableNumber,nameVarNumber,proc {|poke|
  2152.      !poke.isEgg? && poke.hp>0
  2153.   })
  2154. end
  2155.  
  2156. def pbChoosePokemonForTrade(variableNumber,nameVarNumber,wanted)
  2157.   pbChoosePokemon(variableNumber,nameVarNumber,proc {|poke|
  2158.      if wanted.is_a?(String) || wanted.is_a?(Symbol)
  2159.        wanted=getID(PBSpecies,wanted)
  2160.      end
  2161.      return !poke.isEgg? && !(poke.isShadow? rescue false) && poke.species==wanted
  2162.   })
  2163. end
  2164.  
  2165.  
  2166.  
  2167. ################################################################################
  2168. # Checks through the party for something
  2169. ################################################################################
  2170. def pbHasSpecies?(species)
  2171.   if species.is_a?(String) || species.is_a?(Symbol)
  2172.     species=getID(PBSpecies,species)
  2173.   end
  2174.   for pokemon in $Trainer.party
  2175.     next if pokemon.isEgg?
  2176.     return true if pokemon.species==species
  2177.   end
  2178.   return false
  2179. end
  2180.  
  2181. def pbHasFatefulSpecies?(species)
  2182.   if species.is_a?(String) || species.is_a?(Symbol)
  2183.     species=getID(PBSpecies,species)
  2184.   end
  2185.   for pokemon in $Trainer.party
  2186.     next if pokemon.isEgg?
  2187.     return true if pokemon.species==species && pokemon.obtainMode==4
  2188.   end
  2189.   return false
  2190. end
  2191.  
  2192. def pbHasType?(type)
  2193.   if type.is_a?(String) || type.is_a?(Symbol)
  2194.     type=getID(PBTypes,type)
  2195.   end
  2196.   for pokemon in $Trainer.party
  2197.     next if pokemon.isEgg?
  2198.     return true if pokemon.hasType?(type)
  2199.   end
  2200.   return false
  2201. end
  2202.  
  2203. # Checks whether any Pokémon in the party knows the given move, and returns
  2204. # the index of that Pokémon, or nil if no Pokémon has that move.
  2205. def pbCheckMove(move)
  2206.   move=getID(PBMoves,move)
  2207.   return nil if !move || move<=0
  2208.   for i in $Trainer.party
  2209.     next if i.isEgg?
  2210.     for j in i.moves
  2211.       return i if j.id==move
  2212.     end
  2213.   end
  2214.   return nil
  2215. end
  2216.  
  2217.  
  2218.  
  2219. ################################################################################
  2220. # Regional and National Pokédexes
  2221. ################################################################################
  2222. # Gets the Regional Pokédex number of the national species for the specified
  2223. # Regional Dex.  The parameter "region" is zero-based.  For example, if two
  2224. # regions are defined, they would each be specified as 0 and 1.
  2225. def pbGetRegionalNumber(region, nationalSpecies)
  2226.   if nationalSpecies<=0 || nationalSpecies>PBSpecies.maxValue
  2227.     # Return 0 if national species is outside range
  2228.     return 0
  2229.   end
  2230.   pbRgssOpen("Data/regionals.dat","rb"){|f|
  2231.      numRegions=f.fgetw
  2232.      numDexDatas=f.fgetw
  2233.      if region>=0 && region<numRegions
  2234.        f.pos=4+region*numDexDatas*2
  2235.        f.pos+=nationalSpecies*2
  2236.        return f.fgetw
  2237.     end
  2238.   }
  2239.   return 0
  2240. end
  2241.  
  2242. # Gets the National Pokédex number of the specified species and region.  The
  2243. # parameter "region" is zero-based.  For example, if two regions are defined,
  2244. # they would each be specified as 0 and 1.
  2245. def pbGetNationalNumber(region, regionalSpecies)
  2246.   pbRgssOpen("Data/regionals.dat","rb"){|f|
  2247.      numRegions=f.fgetw
  2248.      numDexDatas=f.fgetw
  2249.      if region>=0 && region<numRegions
  2250.        f.pos=4+region*numDexDatas*2
  2251.        # "i" specifies the national species
  2252.        for i in 0...numDexDatas
  2253.          regionalNum=f.fgetw
  2254.          return i if regionalNum==regionalSpecies
  2255.        end
  2256.      end
  2257.   }
  2258.   return 0
  2259. end
  2260.  
  2261. # Gets an array of all national species within the given Regional Dex, sorted by
  2262. # Regional Dex number.  The number of items in the array should be the
  2263. # number of species in the Regional Dex plus 1, since index 0 is considered
  2264. # to be empty.  The parameter "region" is zero-based.  For example, if two
  2265. # regions are defined, they would each be specified as 0 and 1.
  2266. def pbAllRegionalSpecies(region)
  2267.   ret=[0]
  2268.   pbRgssOpen("Data/regionals.dat","rb"){|f|
  2269.      numRegions=f.fgetw
  2270.      numDexDatas=f.fgetw
  2271.      if region>=0 && region<numRegions
  2272.        f.pos=4+region*numDexDatas*2
  2273.        # "i" specifies the national species
  2274.        for i in 0...numDexDatas
  2275.          regionalNum=f.fgetw
  2276.          ret[regionalNum]=i if regionalNum!=0
  2277.        end
  2278.        # Replace unspecified regional
  2279.        # numbers with zeros
  2280.        for i in 0...ret.length
  2281.          ret[i]=0 if !ret[i]
  2282.        end
  2283.      end
  2284.   }
  2285.   return ret
  2286. end
  2287.  
  2288. # Gets the ID number for the current region based on the player's current
  2289. # position.  Returns the value of "defaultRegion" (optional, default is -1) if
  2290. # no region was defined in the game's metadata.  The ID numbers returned by
  2291. # this function depend on the current map's position metadata.
  2292. def pbGetCurrentRegion(defaultRegion=-1)
  2293.   mappos=!$game_map ? nil : pbGetMetadata($game_map.map_id,MetadataMapPosition)
  2294.   if !mappos
  2295.     return defaultRegion # No region defined
  2296.   else
  2297.     return mappos[0]
  2298.   end
  2299. end
  2300.  
  2301. # Decides which Dex lists are able to be viewed (i.e. they are unlocked and have
  2302. # at least 1 seen species in them), and saves all viable dex region numbers
  2303. # (National Dex comes after regional dexes).
  2304. # If the Dex list shown depends on the player's location, this just decides if
  2305. # a species in the current region has been seen - doesn't look at other regions.
  2306. # Here, just used to decide whether to show the Pokédex in the Pause menu.
  2307. def pbSetViableDexes
  2308.   $PokemonGlobal.pokedexViable=[]
  2309.   if DEXDEPENDSONLOCATION
  2310.     region=pbGetCurrentRegion
  2311.     region=-1 if region>=$PokemonGlobal.pokedexUnlocked.length-1
  2312.     if $Trainer.pokedexSeen(region)>0
  2313.       $PokemonGlobal.pokedexViable[0]=region
  2314.     end
  2315.   else
  2316.     numDexes=$PokemonGlobal.pokedexUnlocked.length
  2317.     case numDexes
  2318.     when 1          # National Dex only
  2319.       if $PokemonGlobal.pokedexUnlocked[0]
  2320.         if $Trainer.pokedexSeen>0
  2321.           $PokemonGlobal.pokedexViable.push(0)
  2322.         end
  2323.       end
  2324.     else            # Regional dexes + National Dex
  2325.       for i in 0...numDexes
  2326.         regionToCheck=(i==numDexes-1) ? -1 : i
  2327.         if $PokemonGlobal.pokedexUnlocked[i]
  2328.           if $Trainer.pokedexSeen(regionToCheck)>0
  2329.             $PokemonGlobal.pokedexViable.push(i)
  2330.           end
  2331.         end
  2332.       end
  2333.     end
  2334.   end
  2335. end
  2336.  
  2337. # Unlocks a Dex list.  The National Dex is -1 here (or nil argument).
  2338. def pbUnlockDex(dex=-1)
  2339.   index=dex
  2340.   index=$PokemonGlobal.pokedexUnlocked.length-1 if index<0
  2341.   index=$PokemonGlobal.pokedexUnlocked.length-1 if index>$PokemonGlobal.pokedexUnlocked.length-1
  2342.   $PokemonGlobal.pokedexUnlocked[index]=true
  2343. end
  2344.  
  2345. # Locks a Dex list.  The National Dex is -1 here (or nil argument).
  2346. def pbLockDex(dex=-1)
  2347.   index=dex
  2348.   index=$PokemonGlobal.pokedexUnlocked.length-1 if index<0
  2349.   index=$PokemonGlobal.pokedexUnlocked.length-1 if index>$PokemonGlobal.pokedexUnlocked.length-1
  2350.   $PokemonGlobal.pokedexUnlocked[index]=false
  2351. end
  2352.  
  2353.  
  2354.  
  2355. ################################################################################
  2356. # Other utilities
  2357. ################################################################################
  2358. def pbTextEntry(helptext,minlength,maxlength,variableNumber)
  2359.   $game_variables[variableNumber]=pbEnterText(helptext,minlength,maxlength)
  2360.   $game_map.need_refresh = true if $game_map
  2361. end
  2362.  
  2363. def pbMoveTutorAnnotations(move,movelist=nil)
  2364.   ret=[]
  2365.   for i in 0...6
  2366.     ret[i]=nil
  2367.     next if i>=$Trainer.party.length
  2368.     found=false
  2369.     for j in 0...4
  2370.       if !$Trainer.party[i].isEgg? && $Trainer.party[i].moves[j].id==move
  2371.         ret[i]=_INTL("LEARNED")
  2372.         found=true
  2373.       end
  2374.     end
  2375.     next if found
  2376.     species=$Trainer.party[i].species
  2377.     if !$Trainer.party[i].isEgg? && movelist && movelist.any?{|j| j==species }
  2378.       # Checked data from movelist
  2379.       ret[i]=_INTL("ABLE")
  2380.     elsif !$Trainer.party[i].isEgg? && $Trainer.party[i].isCompatibleWithMove?(move)
  2381.       # Checked data from PBS/tm.txt
  2382.       ret[i]=_INTL("ABLE")
  2383.     else
  2384.       ret[i]=_INTL("NOT ABLE")
  2385.     end
  2386.   end
  2387.   return ret
  2388. end
  2389.  
  2390. def pbMoveTutorChoose(move,movelist=nil,bymachine=false)
  2391.   ret=false
  2392.   if move.is_a?(String) || move.is_a?(Symbol)
  2393.     move=getID(PBMoves,move)
  2394.   end
  2395.   if movelist!=nil && movelist.is_a?(Array)
  2396.     for i in 0...movelist.length
  2397.       if movelist[i].is_a?(String) || movelist[i].is_a?(Symbol)
  2398.         movelist[i]=getID(PBSpecies,movelist[i])
  2399.       end
  2400.     end
  2401.   end
  2402.   pbFadeOutIn(99999){
  2403.      scene=PokemonScreen_Scene.new
  2404.      movename=PBMoves.getName(move)
  2405.      screen=PokemonScreen.new(scene,$Trainer.party)
  2406.      annot=pbMoveTutorAnnotations(move,movelist)
  2407.      screen.pbStartScene(_INTL("Teach which Pokémon?"),false,annot)
  2408.      loop do
  2409.        chosen=screen.pbChoosePokemon
  2410.        if chosen>=0
  2411.          pokemon=$Trainer.party[chosen]
  2412.          if pokemon.isEgg?
  2413.            Kernel.pbMessage(_INTL("{1} can't be taught to an Egg.",movename))
  2414.          elsif (pokemon.isShadow? rescue false)
  2415.            Kernel.pbMessage(_INTL("Shadow Pokémon can't be taught any moves."))
  2416.          elsif movelist && !movelist.any?{|j| j==pokemon.species }
  2417.            Kernel.pbMessage(_INTL("{1} and {2} are not compatible.",pokemon.name,movename))
  2418.            Kernel.pbMessage(_INTL("{1} can't be learned.",movename))
  2419.          elsif !pokemon.isCompatibleWithMove?(move)
  2420.            Kernel.pbMessage(_INTL("{1} and {2} are not compatible.",pokemon.name,movename))
  2421.            Kernel.pbMessage(_INTL("{1} can't be learned.",movename))
  2422.          else
  2423.            if pbLearnMove(pokemon,move,false,bymachine)
  2424.              ret=true
  2425.              break
  2426.            end
  2427.          end
  2428.        else
  2429.          break
  2430.        end  
  2431.      end
  2432.      screen.pbEndScene
  2433.   }
  2434.   return ret # Returns whether the move was learned by a Pokemon
  2435. end
  2436.  
  2437. def pbChooseMove(pokemon,variableNumber,nameVarNumber)
  2438.   return if !pokemon
  2439.   ret=-1
  2440.   pbFadeOutIn(99999){
  2441.      scene=PokemonSummaryScene.new
  2442.      screen=PokemonSummary.new(scene)
  2443.      ret=screen.pbStartForgetScreen([pokemon],0,0)
  2444.   }
  2445.   $game_variables[variableNumber]=ret
  2446.   if ret>=0
  2447.     $game_variables[nameVarNumber]=PBMoves.getName(pokemon.moves[ret].id)
  2448.   else
  2449.     $game_variables[nameVarNumber]=""
  2450.   end
  2451.   $game_map.need_refresh = true if $game_map
  2452. end
  2453.  
  2454. # Opens the Pokémon screen
  2455. def pbPokemonScreen
  2456.   return if !$Trainer
  2457.   sscene=PokemonScreen_Scene.new
  2458.   sscreen=PokemonScreen.new(sscene,$Trainer.party)
  2459.   pbFadeOutIn(99999) { sscreen.pbPokemonScreen }
  2460. end
  2461.  
  2462. def pbSaveScreen
  2463.   ret=false
  2464.   scene=PokemonSaveScene.new
  2465.   screen=PokemonSave.new(scene)
  2466.   ret=screen.pbSaveScreen
  2467.   return ret
  2468. end
  2469.  
  2470. def pbConvertItemToItem(variable,array)
  2471.   item=pbGet(variable)
  2472.   pbSet(variable,0)
  2473.   for i in 0...(array.length/2)
  2474.     if isConst?(item,PBItems,array[2*i])
  2475.       pbSet(variable,getID(PBItems,array[2*i+1]))
  2476.       return
  2477.     end
  2478.   end
  2479. end
  2480.  
  2481. def pbConvertItemToPokemon(variable,array)
  2482.   item=pbGet(variable)
  2483.   pbSet(variable,0)
  2484.   for i in 0...(array.length/2)
  2485.     if isConst?(item,PBItems,array[2*i])
  2486.       pbSet(variable,getID(PBSpecies,array[2*i+1]))
  2487.       return
  2488.     end
  2489.   end
  2490. end
  2491.  
  2492.  
  2493.  
  2494.  
  2495. class PokemonGlobalMetadata
  2496.   attr_accessor :trainerRecording
  2497. end
  2498.  
  2499.  
  2500.  
  2501. def pbRecordTrainer
  2502.   wave=pbRecord(nil,10)
  2503.   if wave
  2504.     $PokemonGlobal.trainerRecording=wave
  2505.     return true
  2506.   end
  2507.   return false
  2508. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement