mirror of
https://github.com/bakustarver/rpgmakermlinux-cicpoffs.git
synced 2025-03-28 14:56:21 +01:00
2510 lines
76 KiB
Ruby
2510 lines
76 KiB
Ruby
################################################################################
|
|
# General purpose utilities
|
|
################################################################################
|
|
def _pbNextComb(comb,length)
|
|
i=comb.length-1
|
|
begin
|
|
valid=true
|
|
for j in i...comb.length
|
|
if j==i
|
|
comb[j]+=1
|
|
else
|
|
comb[j]=comb[i]+(j-i)
|
|
end
|
|
if comb[j]>=length
|
|
valid=false
|
|
break
|
|
end
|
|
end
|
|
return true if valid
|
|
i-=1
|
|
end while i>=0
|
|
return false
|
|
end
|
|
|
|
# Iterates through the array and yields each combination of _num_ elements in
|
|
# the array.
|
|
def pbEachCombination(array,num)
|
|
return if array.length<num || num<=0
|
|
if array.length==num
|
|
yield array
|
|
return
|
|
elsif num==1
|
|
for x in array
|
|
yield [x]
|
|
end
|
|
return
|
|
end
|
|
currentComb=[]
|
|
arr=[]
|
|
for i in 0...num
|
|
currentComb[i]=i
|
|
end
|
|
begin
|
|
for i in 0...num
|
|
arr[i]=array[currentComb[i]]
|
|
end
|
|
yield arr
|
|
end while _pbNextComb(currentComb,array.length)
|
|
end
|
|
|
|
def pbGetCDID()
|
|
sendString=proc{|x|
|
|
mciSendString=Win32API.new('winmm','mciSendString','%w(p,p,l,l)','l')
|
|
next "" if !mciSendString
|
|
buffer="\0"*2000
|
|
x=mciSendString.call(x,buffer,2000,0)
|
|
if x==0
|
|
next buffer.gsub(/\0/,"")
|
|
else
|
|
next ""
|
|
end
|
|
}
|
|
sendString.call("open cdaudio shareable")
|
|
ret=""
|
|
if sendString.call("status cdaudio media present")=="true"
|
|
ret=sendString.call("info cdaudio identity")
|
|
if ret==""
|
|
ret=sendString.call("info cdaudio info identity")
|
|
end
|
|
end
|
|
sendString.call("close cdaudio")
|
|
return ret
|
|
end
|
|
|
|
# Gets the path of the user's "My Documents" folder.
|
|
def pbGetMyDocumentsFolder()
|
|
csidl_personal=0x0005
|
|
shGetSpecialFolderLocation=Win32API.new("shell32.dll","SHGetSpecialFolderLocation","llp","i")
|
|
shGetPathFromIDList=Win32API.new("shell32.dll","SHGetPathFromIDList","lp","i")
|
|
if !shGetSpecialFolderLocation || !shGetPathFromIDList
|
|
return "."
|
|
end
|
|
idl=[0].pack("V")
|
|
ret=shGetSpecialFolderLocation.call(0,csidl_personal,idl)
|
|
return "." if ret!=0
|
|
path="\0"*512
|
|
ret=shGetPathFromIDList.call(idl.unpack("V")[0],path)
|
|
return "." if ret==0
|
|
return path.gsub(/\0/,"")
|
|
end
|
|
|
|
# Returns a country ID
|
|
# http://msdn.microsoft.com/en-us/library/dd374073%28VS.85%29.aspx?
|
|
def pbGetCountry()
|
|
getUserGeoID=Win32API.new("kernel32","GetUserGeoID","l","i") rescue nil
|
|
if getUserGeoID
|
|
return getUserGeoID.call(16)
|
|
end
|
|
return 0
|
|
end
|
|
|
|
# Returns a language ID
|
|
def pbGetLanguage()
|
|
getUserDefaultLangID=Win32API.new("kernel32","GetUserDefaultLangID","","i") rescue nil
|
|
ret=0
|
|
if getUserDefaultLangID
|
|
ret=getUserDefaultLangID.call()&0x3FF
|
|
end
|
|
if ret==0 # Unknown
|
|
ret=MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER,
|
|
"Control Panel\\Desktop\\ResourceLocale","",0)
|
|
ret=MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER,
|
|
"Control Panel\\International","Locale","0").to_i(16) if ret==0
|
|
ret=ret&0x3FF
|
|
return 0 if ret==0 # Unknown
|
|
end
|
|
return 1 if ret==0x11 # Japanese
|
|
return 2 if ret==0x09 # English
|
|
return 3 if ret==0x0C # French
|
|
return 4 if ret==0x10 # Italian
|
|
return 5 if ret==0x07 # German
|
|
return 7 if ret==0x0A # Spanish
|
|
return 8 if ret==0x12 # Korean
|
|
return 2 # Use 'English' by default
|
|
end
|
|
|
|
# Converts a Celsius temperature to Fahrenheit.
|
|
def toFahrenheit(celsius)
|
|
return (celsius*9.0/5.0).round+32
|
|
end
|
|
|
|
# Converts a Fahrenheit temperature to Celsius.
|
|
def toCelsius(fahrenheit)
|
|
return ((fahrenheit-32)*5.0/9.0).round
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Linear congruential random number generator
|
|
################################################################################
|
|
class LinearCongRandom
|
|
def initialize(mul, add, seed=nil)
|
|
@s1=mul
|
|
@s2=add
|
|
@seed=seed
|
|
@seed=(Time.now.to_i&0xffffffff) if !@seed
|
|
@seed=(@seed+0xFFFFFFFF)+1 if @seed<0
|
|
end
|
|
|
|
def self.dsSeed
|
|
t=Time.now
|
|
seed = (((t.mon * t.mday + t.min + t.sec)&0xFF) << 24) | (t.hour << 16) | (t.year - 2000)
|
|
seed=(seed+0xFFFFFFFF)+1 if seed<0
|
|
return seed
|
|
end
|
|
|
|
def self.pokemonRNG
|
|
self.new(0x41c64e6d,0x6073,self.dsSeed)
|
|
end
|
|
|
|
def self.pokemonRNGInverse
|
|
self.new(0xeeb9eb65,0xa3561a1,self.dsSeed)
|
|
end
|
|
|
|
def self.pokemonARNG
|
|
self.new(0x6C078965,0x01,self.dsSeed)
|
|
end
|
|
|
|
def getNext16 # calculates @seed * @s1 + @s2
|
|
@seed=((((@seed & 0x0000ffff) * (@s1 & 0x0000ffff)) & 0x0000ffff) |
|
|
(((((((@seed & 0x0000ffff) * (@s1 & 0x0000ffff)) & 0xffff0000) >> 16) +
|
|
((((@seed & 0xffff0000) >> 16) * (@s1 & 0x0000ffff)) & 0x0000ffff) +
|
|
(((@seed & 0x0000ffff) * ((@s1 & 0xffff0000) >> 16)) & 0x0000ffff)) &
|
|
0x0000ffff) << 16)) + @s2
|
|
r=(@seed>>16)
|
|
r=(r+0xFFFFFFFF)+1 if r<0
|
|
return r
|
|
end
|
|
|
|
def getNext
|
|
r=(getNext16()<<16)|(getNext16())
|
|
r=(r+0xFFFFFFFF)+1 if r<0
|
|
return r
|
|
end
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# JavaScript-related utilities
|
|
################################################################################
|
|
# Returns true if the given string represents a valid object in JavaScript
|
|
# Object Notation, and false otherwise.
|
|
|
|
|
|
|
|
|
|
def pbIsJsonString(str)
|
|
|
|
return false if !str || str.strip.empty?
|
|
|
|
# Regular expressions for matching parts of a JSON string
|
|
d = /(?:^|:|,)(?: ?\[)+/
|
|
charEscapes = /\\[\"\\\/nrtubf]/
|
|
|
|
# Match string literals that may contain escaped characters
|
|
# This will match strings with valid JSON escapes, such as \", \\, \n, \r, etc.
|
|
stringLiterals = /"(?:[^"\\\n\r\x00-\x1f\x7f\x80-\x9f\\]|\\.)*"/
|
|
|
|
# White space matching
|
|
whiteSpace = /[\s]+/
|
|
|
|
# Pre-process the string to replace escapes, literals, and whitespace
|
|
str = str.gsub(charEscapes, "@").gsub(stringLiterals, "true").gsub(whiteSpace, " ")
|
|
|
|
# Prevent cases like "truetrue", "true true", "true[true]", or other malformed patterns
|
|
otherLiterals = /(true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)(?! ?[0-9a-z\-\[\{\"])/
|
|
|
|
str = str.gsub(otherLiterals, "]").gsub(d, "")
|
|
|
|
# Check if the string matches the format of a valid JSON-like structure
|
|
return str =~ /^[\],:{}\s]*$/ ? true : false
|
|
|
|
end
|
|
|
|
|
|
|
|
# Returns a Ruby object that corresponds to the given string, which is encoded in
|
|
# JavaScript Object Notation (JSON). Returns nil if the string is not valid JSON.
|
|
def pbParseJson(str)
|
|
if !pbIsJsonString(str)
|
|
return nil
|
|
end
|
|
stringRE=/(\"(\\[\"\'\\rntbf]|\\u[0-9A-Fa-f]{4,4}|[^\\\"])*\")/ #"
|
|
strings=[]
|
|
str=str.gsub(stringRE){
|
|
sl=strings.length
|
|
ss=$1
|
|
if ss.include?("\\u")
|
|
ss.gsub!(/\\u([0-9A-Fa-f]{4,4})/){
|
|
codepoint=$1.to_i(16)
|
|
if codepoint<=0x7F
|
|
next sprintf("\\x%02X",codepoint)
|
|
elsif codepoint<=0x7FF
|
|
next sprintf("%s%s",
|
|
(0xC0|((codepoint>>6)&0x1F)).chr,
|
|
(0x80|(codepoint &0x3F)).chr)
|
|
else
|
|
next sprintf("%s%s%s",
|
|
(0xE0|((codepoint>>12)&0x0F)).chr,
|
|
(0x80|((codepoint>>6)&0x3F)).chr,
|
|
(0x80|(codepoint &0x3F)).chr)
|
|
end
|
|
}
|
|
end
|
|
strings.push(eval(ss))
|
|
next sprintf("strings[%d]",sl)
|
|
}
|
|
str=str.gsub(/\:/,"=>")
|
|
str=str.gsub(/null/,"nil")
|
|
return eval("("+str+")")
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# XML-related utilities
|
|
################################################################################
|
|
# Represents XML content.
|
|
class MiniXmlContent
|
|
attr_reader :value
|
|
|
|
def initialize(value)
|
|
@value=value
|
|
end
|
|
end
|
|
|
|
|
|
|
|
# Represents an XML element.
|
|
class MiniXmlElement
|
|
attr_accessor :name,:attributes,:children
|
|
|
|
def initialize(name)
|
|
@name=name
|
|
@attributes={}
|
|
@children=[]
|
|
end
|
|
|
|
# Gets the value of the attribute with the given name, or nil if it doesn't
|
|
# exist.
|
|
def a(name)
|
|
self.attributes[name]
|
|
end
|
|
|
|
# Gets the entire text of this element.
|
|
def value
|
|
ret=""
|
|
for c in @children
|
|
ret+=c.value
|
|
end
|
|
return ret
|
|
end
|
|
|
|
# Gets the first child of this element with the given name, or nil if it
|
|
# doesn't exist.
|
|
def e(name)
|
|
for c in @children
|
|
return c if c.is_a?(MiniXmlElement) && c.name==name
|
|
end
|
|
return nil
|
|
end
|
|
|
|
def eachElementNamed(name)
|
|
for c in @children
|
|
yield c if c.is_a?(MiniXmlElement) && c.name==name
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
# A small class for reading simple XML documents. Such documents must
|
|
# meet the following restrictions:
|
|
# They may contain comments and processing instructions, but they are
|
|
# ignored.
|
|
# They can't contain any entity references other than 'gt', 'lt',
|
|
# 'amp', 'apos', or 'quot'.
|
|
# They can't contain a DOCTYPE declaration or DTDs.
|
|
class MiniXmlReader
|
|
def initialize(data)
|
|
@root=nil
|
|
@elements=[]
|
|
@done=false
|
|
@data=data
|
|
@content=""
|
|
end
|
|
|
|
def createUtf8(codepoint) #:nodoc:
|
|
raise ArgumentError.new("Illegal character") if codepoint<9 ||
|
|
codepoint==11||codepoint==12||(codepoint>=14 && codepoint<32) ||
|
|
codepoint==0xFFFE||codepoint==0xFFFF||(codepoint>=0xD800 && codepoint<0xE000)
|
|
if codepoint<=0x7F
|
|
return codepoint.chr
|
|
elsif codepoint<=0x7FF
|
|
str=(0xC0|((codepoint>>6)&0x1F)).chr
|
|
str+=(0x80|(codepoint &0x3F)).chr
|
|
return str
|
|
elsif codepoint<=0xFFFF
|
|
str=(0xE0|((codepoint>>12)&0x0F)).chr
|
|
str+=(0x80|((codepoint>>6)&0x3F)).chr
|
|
str+=(0x80|(codepoint &0x3F)).chr
|
|
return str
|
|
elsif codepoint<=0x10FFFF
|
|
str=(0xF0|((codepoint>>18)&0x07)).chr
|
|
str+=(0x80|((codepoint>>12)&0x3F)).chr
|
|
str+=(0x80|((codepoint>>6)&0x3F)).chr
|
|
str+=(0x80|(codepoint &0x3F)).chr
|
|
return str
|
|
else
|
|
raise ArgumentError.new("Illegal character")
|
|
end
|
|
return str
|
|
end
|
|
|
|
def unescape(attr) #:nodoc:
|
|
attr=attr.gsub(/\r(\n|$|(?=[^\n]))/,"\n")
|
|
raise ArgumentError.new("Attribute value contains '<'") if attr.include?("<")
|
|
attr=attr.gsub(/&(lt|gt|apos|quot|amp|\#([0-9]+)|\#x([0-9a-fA-F]+));|([\n\r\t])/){
|
|
next " " if $4=="\n"||$4=="\r"||$4=="\t"
|
|
next "<" if $1=="lt"
|
|
next ">" if $1=="gt"
|
|
next "'" if $1=="apos"
|
|
next "\"" if $1=="quot"
|
|
next "&" if $1=="amp"
|
|
next createUtf8($2.to_i) if $2
|
|
next createUtf8($3.to_i(16)) if $3
|
|
}
|
|
return attr
|
|
end
|
|
|
|
def readAttributes(attribs) #:nodoc:
|
|
ret={}
|
|
while attribs.length>0
|
|
if attribs[/(\s+([\w\-]+)\s*\=\s*\"([^\"]*)\")/]
|
|
attribs=attribs[$1.length,attribs.length]
|
|
name=$2; value=$3
|
|
if ret[name]!=nil
|
|
raise ArgumentError.new("Attribute already exists")
|
|
end
|
|
ret[name]=unescape(value)
|
|
elsif attribs[/(\s+([\w\-]+)\s*\=\s*\'([^\']*)\')/]
|
|
attribs=attribs[$1.length,attribs.length]
|
|
name=$2; value=$3
|
|
if ret[name]!=nil
|
|
raise ArgumentError.new("Attribute already exists")
|
|
end
|
|
ret[name]=unescape(value)
|
|
else
|
|
raise ArgumentError.new("Can't parse attributes")
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
# Reads the entire contents of an XML document. Returns the root element of
|
|
# the document or raises an ArgumentError if an error occurs.
|
|
def read
|
|
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*\?>)/]
|
|
# Ignore XML declaration
|
|
@data=@data[$1.length,@data.length]
|
|
end
|
|
while readOneElement(); end
|
|
return @root
|
|
end
|
|
|
|
def readOneElement #:nodoc:
|
|
if @data[/\A\s*\z/]
|
|
@data=""
|
|
if !@root
|
|
raise ArgumentError.new("Not an XML document.")
|
|
elsif !@done
|
|
raise ArgumentError.new("Unexpected end of document.")
|
|
end
|
|
return false
|
|
end
|
|
if @data[/\A(\s*<([\w\-]+)((?:\s+[\w\-]+\s*\=\s*(?:\"[^\"]*\"|\'[^\']*\'))*)\s*(\/>|>))/]
|
|
@data=@data[$1.length,@data.length]
|
|
elementName=$2
|
|
attributes=$3
|
|
endtag=$4
|
|
if @done
|
|
raise ArgumentError.new("Element tag at end of document")
|
|
end
|
|
if @content.length>0 && @elements.length>0
|
|
@elements[@elements.length-1].children.push(MiniXmlContent.new(@content))
|
|
@content=""
|
|
end
|
|
element=MiniXmlElement.new(elementName)
|
|
element.attributes=readAttributes(attributes)
|
|
if !@root
|
|
@root=element
|
|
else
|
|
@elements[@elements.length-1].children.push(element)
|
|
end
|
|
if endtag==">"
|
|
@elements.push(element)
|
|
else
|
|
if @elements.length==0
|
|
@done=true
|
|
end
|
|
end
|
|
elsif @data[/\A(<!--([\s\S]*?)-->)/]
|
|
# ignore comments
|
|
if $2.include?("--")
|
|
raise ArgumentError.new("Incorrect comment")
|
|
end
|
|
@data=@data[$1.length,@data.length]
|
|
elsif @data[/\A(<\?([\w\-]+)\s+[\s\S]*?\?>)/]
|
|
# ignore processing instructions
|
|
@data=@data[$1.length,@data.length]
|
|
if $2.downcase=="xml"
|
|
raise ArgumentError.new("'xml' processing instruction not allowed")
|
|
end
|
|
elsif @data[/\A(<\?([\w\-]+)\?>)/]
|
|
# ignore processing instructions
|
|
@data=@data[$1.length,@data.length]
|
|
if $2.downcase=="xml"
|
|
raise ArgumentError.new("'xml' processing instruction not allowed")
|
|
end
|
|
elsif @data[/\A(\s*<\/([\w\-]+)>)/]
|
|
@data=@data[$1.length,@data.length]
|
|
elementName=$2
|
|
if @done
|
|
raise ArgumentError.new("End tag at end of document")
|
|
end
|
|
if @elements.length==0
|
|
raise ArgumentError.new("Unexpected end tag")
|
|
elsif @elements[@elements.length-1].name!=elementName
|
|
raise ArgumentError.new("Incorrect end tag")
|
|
else
|
|
if @content.length>0
|
|
@elements[@elements.length-1].children.push(MiniXmlContent.new(@content))
|
|
@content=""
|
|
end
|
|
@elements.pop()
|
|
if @elements.length==0
|
|
@done=true
|
|
end
|
|
end
|
|
else
|
|
if @elements.length>0
|
|
# Parse content
|
|
if @data[/\A([^<&]+)/]
|
|
content=$1
|
|
@data=@data[content.length,@data.length]
|
|
if content.include?("]]>")
|
|
raise ArgumentError.new("Incorrect content")
|
|
end
|
|
content.gsub!(/\r(\n|\z|(?=[^\n]))/,"\n")
|
|
@content+=content
|
|
elsif @data[/\A(<\!\[CDATA\[([\s\S]*?)\]\]>)/]
|
|
content=$2
|
|
@data=@data[$1.length,@data.length]
|
|
content.gsub!(/\r(\n|\z|(?=[^\n]))/,"\n")
|
|
@content+=content
|
|
elsif @data[/\A(&(lt|gt|apos|quot|amp|\#([0-9]+)|\#x([0-9a-fA-F]+));)/]
|
|
@data=@data[$1.length,@data.length]
|
|
content=""
|
|
if $2=="lt"; content="<"
|
|
elsif $2=="gt"; content=">"
|
|
elsif $2=="apos"; content="'"
|
|
elsif $2=="quot"; content="\""
|
|
elsif $2=="amp"; content="&"
|
|
elsif $3; content=createUtf8($2.to_i)
|
|
elsif $4; content=createUtf8($3.to_i(16))
|
|
end
|
|
@content+=content
|
|
elsif !@data[/\A</]
|
|
raise ArgumentError.new("Can't read XML content")
|
|
end
|
|
else
|
|
raise ArgumentError.new("Can't parse XML")
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Player-related utilities, random name generator
|
|
################################################################################
|
|
def pbChangePlayer(id)
|
|
return false if id<0 || id>=8
|
|
meta=pbGetMetadata(0,MetadataPlayerA+id)
|
|
return false if !meta
|
|
$Trainer.trainertype=meta[0] if $Trainer
|
|
$game_player.character_name=meta[1]
|
|
$game_player.character_hue=0
|
|
$PokemonGlobal.playerID=id
|
|
$Trainer.metaID=id if $Trainer
|
|
end
|
|
|
|
def pbGetPlayerGraphic
|
|
id=$PokemonGlobal.playerID
|
|
return "" if id<0 || id>=8
|
|
meta=pbGetMetadata(0,MetadataPlayerA+id)
|
|
return "" if !meta
|
|
return pbPlayerSpriteFile(meta[0])
|
|
end
|
|
|
|
def pbGetPlayerTrainerType
|
|
id=$PokemonGlobal.playerID
|
|
return 0 if id<0 || id>=8
|
|
meta=pbGetMetadata(0,MetadataPlayerA+id)
|
|
return 0 if !meta
|
|
return meta[0]
|
|
end
|
|
|
|
def pbGetTrainerTypeGender(trainertype)
|
|
ret=2 # 2 = gender unknown
|
|
pbRgssOpen("Data/trainertypes.dat","rb"){|f|
|
|
trainertypes=Marshal.load(f)
|
|
if !trainertypes[trainertype]
|
|
ret=2
|
|
else
|
|
ret=trainertypes[trainertype][7]
|
|
ret=2 if !ret
|
|
end
|
|
}
|
|
return ret
|
|
end
|
|
|
|
def pbTrainerName(name=nil,outfit=0)
|
|
if $PokemonGlobal.playerID<0
|
|
pbChangePlayer(0)
|
|
end
|
|
trainertype=pbGetPlayerTrainerType
|
|
trname=name
|
|
$Trainer=PokeBattle_Trainer.new(trname,trainertype)
|
|
$Trainer.outfit=outfit
|
|
if trname==nil
|
|
trname=pbEnterPlayerName(_INTL("Your name?"),0,7)
|
|
if trname==""
|
|
# gender=pbGetTrainerTypeGender(trainertype)
|
|
# trname=pbSuggestTrainerName(gender)
|
|
#REDMAGE - replaced the above two lines with the one below
|
|
trname=[_INTL("Simon"),_INTL("Sofia")][$PokemonGlobal.playerID]
|
|
end
|
|
end
|
|
$Trainer.name=trname
|
|
$PokemonBag=PokemonBag.new
|
|
$PokemonTemp.begunNewGame=true
|
|
end
|
|
|
|
def pbSuggestTrainerName(gender)
|
|
userName=pbGetUserName()
|
|
userName=userName.gsub(/\s+.*$/,"")
|
|
if userName.length>0 && userName.length<7
|
|
userName[0,1]=userName[0,1].upcase
|
|
return userName
|
|
end
|
|
userName=userName.gsub(/\d+$/,"")
|
|
if userName.length>0 && userName.length<7
|
|
userName[0,1]=userName[0,1].upcase
|
|
return userName
|
|
end
|
|
owner=MiniRegistry.get(MiniRegistry::HKEY_LOCAL_MACHINE,
|
|
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
|
|
"RegisteredOwner","")
|
|
owner=owner.gsub(/\s+.*$/,"")
|
|
if owner.length>0 && owner.length<7
|
|
owner[0,1]=owner[0,1].upcase
|
|
return owner
|
|
end
|
|
return getRandomNameEx(gender,nil,1,7)
|
|
end
|
|
|
|
def pbGetUserName()
|
|
buffersize=100
|
|
getUserName=Win32API.new('advapi32.dll','GetUserName','pp','i')
|
|
10.times do
|
|
size=[buffersize].pack("V")
|
|
buffer="\0"*buffersize
|
|
if getUserName.call(buffer,size)!=0
|
|
return buffer.gsub(/\0/,"")
|
|
end
|
|
buffersize+=200
|
|
end
|
|
return ""
|
|
end
|
|
|
|
def getRandomNameEx(type,variable,upper,maxLength=100)
|
|
return "" if maxLength<=0
|
|
name=""
|
|
50.times {
|
|
name=""
|
|
formats=[]
|
|
case type
|
|
when 0 # Names for males
|
|
formats=%w( F5 BvE FE FE5 FEvE )
|
|
when 1 # Names for females
|
|
formats=%w( vE6 vEvE6 BvE6 B4 v3 vEv3 Bv3 )
|
|
when 2 # Neutral gender names
|
|
formats=%w( WE WEU WEvE BvE BvEU BvEvE )
|
|
else
|
|
return ""
|
|
end
|
|
format=formats[rand(formats.length)]
|
|
format.scan(/./) {|c|
|
|
case c
|
|
when "c" # consonant
|
|
set=%w( b c d f g h j k l m n p r s t v w x z )
|
|
name+=set[rand(set.length)]
|
|
when "v" # vowel
|
|
set=%w( a a a e e e i i i o o o u u u )
|
|
name+=set[rand(set.length)]
|
|
when "W" # beginning vowel
|
|
set=%w( a a a e e e i i i o o o u u u au au ay ay
|
|
ea ea ee ee oo oo ou ou )
|
|
name+=set[rand(set.length)]
|
|
when "U" # ending vowel
|
|
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 )
|
|
name+=set[rand(set.length)]
|
|
when "B" # beginning consonant
|
|
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 )
|
|
set2=%w(
|
|
bl br ch cl cr dr fr fl gl gr kh kl kr ph pl pr sc sk sl
|
|
sm sn sp st sw th tr tw vl zh )
|
|
name+=rand(3)>0 ? set1[rand(set1.length)] : set2[rand(set2.length)]
|
|
when "E" # ending consonant
|
|
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 )
|
|
set2=%w( bb bs ch cs ds fs ft gs gg ld ls
|
|
nd ng nk rn kt ks
|
|
ms ns ph pt ps sk sh sp ss st rd
|
|
rn rp rm rt rk ns th zh)
|
|
name+=rand(3)>0 ? set1[rand(set1.length)] : set2[rand(set2.length)]
|
|
when "f" # consonant and vowel
|
|
set=%w( iz us or )
|
|
name+=set[rand(set.length)]
|
|
when "F" # consonant and vowel
|
|
set=%w( bo ba be bu re ro si mi zho se nya gru gruu glee gra glo ra do zo ri
|
|
di ze go ga pree pro po pa ka ki ku de da ma mo le la li )
|
|
name+=set[rand(set.length)]
|
|
when "2"
|
|
set=%w( c f g k l p r s t )
|
|
name+=set[rand(set.length)]
|
|
when "3"
|
|
set=%w( nka nda la li ndra sta cha chie )
|
|
name+=set[rand(set.length)]
|
|
when "4"
|
|
set=%w( una ona ina ita ila ala ana ia iana )
|
|
name+=set[rand(set.length)]
|
|
when "5"
|
|
set=%w( e e o o ius io u u ito io ius us )
|
|
name+=set[rand(set.length)]
|
|
when "6"
|
|
set=%w( a a a elle ine ika ina ita ila ala ana )
|
|
name+=set[rand(set.length)]
|
|
end
|
|
}
|
|
break if name.length<=maxLength
|
|
}
|
|
name=name[0,maxLength]
|
|
case upper
|
|
when 0
|
|
name=name.upcase
|
|
when 1
|
|
name[0,1]=name[0,1].upcase
|
|
end
|
|
if $game_variables && variable
|
|
$game_variables[variable]=name
|
|
$game_map.need_refresh = true if $game_map
|
|
end
|
|
return name
|
|
end
|
|
|
|
def getRandomName(maxLength=100)
|
|
return getRandomNameEx(2,nil,nil,maxLength)
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Event timing utilities
|
|
################################################################################
|
|
def pbTimeEvent(variableNumber,secs=86400)
|
|
if variableNumber && variableNumber>=0
|
|
if $game_variables
|
|
secs=0 if secs<0
|
|
timenow=pbGetTimeNow
|
|
$game_variables[variableNumber]=[timenow.to_f,secs]
|
|
$game_map.refresh if $game_map
|
|
end
|
|
end
|
|
end
|
|
|
|
def pbTimeEventDays(variableNumber,days=0)
|
|
if variableNumber && variableNumber>=0
|
|
if $game_variables
|
|
days=0 if days<0
|
|
timenow=pbGetTimeNow
|
|
time=timenow.to_f
|
|
expiry=(time%86400.0)+(days*86400.0)
|
|
$game_variables[variableNumber]=[time,expiry-time]
|
|
$game_map.refresh if $game_map
|
|
end
|
|
end
|
|
end
|
|
|
|
def pbTimeEventValid(variableNumber)
|
|
retval=false
|
|
if variableNumber && variableNumber>=0 && $game_variables
|
|
value=$game_variables[variableNumber]
|
|
if value.is_a?(Array)
|
|
timenow=pbGetTimeNow
|
|
retval=(timenow.to_f - value[0] > value[1]) # value[1] is age in seconds
|
|
retval=false if value[1]<=0 # zero age
|
|
end
|
|
if !retval
|
|
$game_variables[variableNumber]=0
|
|
$game_map.refresh if $game_map
|
|
end
|
|
end
|
|
return retval
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Constants utilities
|
|
################################################################################
|
|
def isConst?(val,mod,constant)
|
|
begin
|
|
isdef=mod.const_defined?(constant.to_sym)
|
|
return false if !isdef
|
|
rescue
|
|
return false
|
|
end
|
|
return (val==mod.const_get(constant.to_sym))
|
|
end
|
|
|
|
def hasConst?(mod,constant)
|
|
return false if !mod || !constant || constant==""
|
|
return mod.const_defined?(constant.to_sym) rescue false
|
|
end
|
|
|
|
def getConst(mod,constant)
|
|
return nil if !mod || !constant || constant==""
|
|
return mod.const_get(constant.to_sym) rescue nil
|
|
end
|
|
|
|
def getID(mod,constant)
|
|
return nil if !mod || !constant || constant==""
|
|
if constant.is_a?(Symbol) || constant.is_a?(String)
|
|
if (mod.const_defined?(constant.to_sym) rescue false)
|
|
return mod.const_get(constant.to_sym) rescue 0
|
|
else
|
|
return 0
|
|
end
|
|
else
|
|
return constant
|
|
end
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Implements methods that act on arrays of items. Each element in an item
|
|
# array is itself an array of [itemID, itemCount].
|
|
# Used by the Bag, PC item storage, and Triple Triad.
|
|
################################################################################
|
|
module ItemStorageHelper
|
|
# Returns the quantity of the given item in the items array, maximum size per slot, and item ID
|
|
def self.pbQuantity(items,maxsize,item)
|
|
ret=0
|
|
for i in 0...maxsize
|
|
itemslot=items[i]
|
|
if itemslot && itemslot[0]==item
|
|
ret+=itemslot[1]
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
# Deletes an item from items array, maximum size per slot, item, and number of items to delete
|
|
def self.pbDeleteItem(items,maxsize,item,qty)
|
|
raise "Invalid value for qty: #{qty}" if qty<0
|
|
return true if qty==0
|
|
ret=false
|
|
for i in 0...maxsize
|
|
itemslot=items[i]
|
|
if itemslot && itemslot[0]==item
|
|
amount=[qty,itemslot[1]].min
|
|
itemslot[1]-=amount
|
|
qty-=amount
|
|
items[i]=nil if itemslot[1]==0
|
|
if qty==0
|
|
ret=true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
items.compact!
|
|
return ret
|
|
end
|
|
|
|
def self.pbCanStore?(items,maxsize,maxPerSlot,item,qty)
|
|
raise "Invalid value for qty: #{qty}" if qty<0
|
|
return true if qty==0
|
|
for i in 0...maxsize
|
|
itemslot=items[i]
|
|
if !itemslot
|
|
qty-=[qty,maxPerSlot].min
|
|
return true if qty==0
|
|
elsif itemslot[0]==item && itemslot[1]<maxPerSlot
|
|
newamt=itemslot[1]
|
|
newamt=[newamt+qty,maxPerSlot].min
|
|
qty-=(newamt-itemslot[1])
|
|
return true if qty==0
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
def self.pbStoreItem(items,maxsize,maxPerSlot,item,qty,sorting=false)
|
|
raise "Invalid value for qty: #{qty}" if qty<0
|
|
return true if qty==0
|
|
for i in 0...maxsize
|
|
itemslot=items[i]
|
|
if !itemslot
|
|
items[i]=[item,[qty,maxPerSlot].min]
|
|
qty-=items[i][1]
|
|
if sorting
|
|
items.sort! if POCKETAUTOSORT[$ItemData[item][ITEMPOCKET]]
|
|
end
|
|
return true if qty==0
|
|
elsif itemslot[0]==item && itemslot[1]<maxPerSlot
|
|
newamt=itemslot[1]
|
|
newamt=[newamt+qty,maxPerSlot].min
|
|
qty-=(newamt-itemslot[1])
|
|
itemslot[1]=newamt
|
|
return true if qty==0
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# General-purpose utilities with dependencies
|
|
################################################################################
|
|
# Similar to pbFadeOutIn, but pauses the music as it fades out.
|
|
# Requires scripts "Audio" (for bgm_pause) and "SpriteWindow" (for pbFadeOutIn).
|
|
def pbFadeOutInWithMusic(zViewport)
|
|
playingBGS=$game_system.getPlayingBGS
|
|
playingBGM=$game_system.getPlayingBGM
|
|
$game_system.bgm_pause(1.0)
|
|
$game_system.bgs_pause(1.0)
|
|
pos=$game_system.bgm_position
|
|
pbFadeOutIn(zViewport) {
|
|
yield
|
|
$game_system.bgm_position=pos
|
|
$game_system.bgm_resume(playingBGM)
|
|
$game_system.bgs_resume(playingBGS)
|
|
}
|
|
end
|
|
|
|
# Gets the wave data from a file and displays an message if an error occurs.
|
|
# Can optionally delete the wave file (this is useful if the file was a
|
|
# temporary file created by a recording).
|
|
# Requires the script AudioUtilities
|
|
# Requires the script "PokemonMessages"
|
|
def getWaveDataUI(filename,deleteFile=false)
|
|
error=getWaveData(filename)
|
|
if deleteFile
|
|
begin
|
|
File.delete(filename)
|
|
rescue Errno::EINVAL, Errno::EACCES, Errno::ENOENT
|
|
end
|
|
end
|
|
case error
|
|
when 1
|
|
Kernel.pbMessage(_INTL("The recorded data could not be found or saved."))
|
|
when 2
|
|
Kernel.pbMessage(_INTL("The recorded data was in an invalid format."))
|
|
when 3
|
|
Kernel.pbMessage(_INTL("The recorded data's format is not supported."))
|
|
when 4
|
|
Kernel.pbMessage(_INTL("There was no sound in the recording. Please ensure that a microphone is attached to the computer and is ready."))
|
|
else
|
|
return error
|
|
end
|
|
return nil
|
|
end
|
|
|
|
# Starts recording, and displays a message if the recording failed to start.
|
|
# Returns true if successful, false otherwise
|
|
# Requires the script AudioUtilities
|
|
# Requires the script "PokemonMessages"
|
|
def beginRecordUI
|
|
code=beginRecord
|
|
case code
|
|
when 0; return true
|
|
when 256+66
|
|
Kernel.pbMessage(_INTL("All recording devices are in use. Recording is not possible now."))
|
|
return false
|
|
when 256+72
|
|
Kernel.pbMessage(_INTL("No supported recording device was found. Recording is not possible."))
|
|
return false
|
|
else
|
|
buffer="\0"*256
|
|
MciErrorString.call(code,buffer,256)
|
|
Kernel.pbMessage(_INTL("Recording failed: {1}",buffer.gsub(/\x00/,"")))
|
|
return false
|
|
end
|
|
end
|
|
|
|
def pbHideVisibleObjects
|
|
visibleObjects=[]
|
|
ObjectSpace.each_object(Sprite){|o|
|
|
if !o.disposed? && o.visible
|
|
visibleObjects.push(o)
|
|
o.visible=false
|
|
end
|
|
}
|
|
ObjectSpace.each_object(Viewport){|o|
|
|
if !pbDisposed?(o) && o.visible
|
|
visibleObjects.push(o)
|
|
o.visible=false
|
|
end
|
|
}
|
|
ObjectSpace.each_object(Plane){|o|
|
|
if !o.disposed? && o.visible
|
|
visibleObjects.push(o)
|
|
o.visible=false
|
|
end
|
|
}
|
|
ObjectSpace.each_object(Tilemap){|o|
|
|
if !o.disposed? && o.visible
|
|
visibleObjects.push(o)
|
|
o.visible=false
|
|
end
|
|
}
|
|
ObjectSpace.each_object(Window){|o|
|
|
if !o.disposed? && o.visible
|
|
visibleObjects.push(o)
|
|
o.visible=false
|
|
end
|
|
}
|
|
return visibleObjects
|
|
end
|
|
|
|
def pbShowObjects(visibleObjects)
|
|
for o in visibleObjects
|
|
if !pbDisposed?(o)
|
|
o.visible=true
|
|
end
|
|
end
|
|
end
|
|
|
|
def pbLoadRpgxpScene(scene)
|
|
return if !$scene.is_a?(Scene_Map)
|
|
oldscene=$scene
|
|
$scene=scene
|
|
Graphics.freeze
|
|
oldscene.disposeSpritesets
|
|
visibleObjects=pbHideVisibleObjects
|
|
Graphics.transition(15)
|
|
Graphics.freeze
|
|
while $scene && !$scene.is_a?(Scene_Map)
|
|
$scene.main
|
|
end
|
|
Graphics.transition(15)
|
|
Graphics.freeze
|
|
oldscene.createSpritesets
|
|
pbShowObjects(visibleObjects)
|
|
Graphics.transition(20)
|
|
$scene=oldscene
|
|
end
|
|
|
|
# Gets the value of a variable.
|
|
def pbGet(id)
|
|
return 0 if !id || !$game_variables
|
|
return $game_variables[id]
|
|
end
|
|
|
|
# Sets the value of a variable.
|
|
def pbSet(id,value)
|
|
if id && id>=0
|
|
$game_variables[id]=value if $game_variables
|
|
$game_map.need_refresh = true if $game_map
|
|
end
|
|
end
|
|
|
|
# Runs a common event and waits until the common event is finished.
|
|
# Requires the script "PokemonMessages"
|
|
def pbCommonEvent(id)
|
|
return false if id<0
|
|
ce=$data_common_events[id]
|
|
return false if !ce
|
|
celist=ce.list
|
|
interp=Interpreter.new
|
|
interp.setup(celist,0)
|
|
begin
|
|
Graphics.update
|
|
Input.update
|
|
interp.update
|
|
pbUpdateSceneMap
|
|
end while interp.running?
|
|
return true
|
|
end
|
|
|
|
def pbExclaim(event,id=EXCLAMATION_ANIMATION_ID,tinting=false)
|
|
if event.is_a?(Array)
|
|
sprite=nil
|
|
done=[]
|
|
for i in event
|
|
if !done.include?(i.id)
|
|
sprite=$scene.spriteset.addUserAnimation(id,i.x,i.y,tinting)
|
|
done.push(i.id)
|
|
end
|
|
end
|
|
else
|
|
sprite=$scene.spriteset.addUserAnimation(id,event.x,event.y-1,tinting) #Nave exclamaition mark fix (added that -1)
|
|
end
|
|
while !sprite.disposed?
|
|
Graphics.update
|
|
Input.update
|
|
pbUpdateSceneMap
|
|
end
|
|
end
|
|
|
|
def pbNoticePlayer(event)
|
|
if !pbFacingEachOther(event,$game_player) || !Input.press?(Input::C)
|
|
pbExclaim(event)
|
|
end
|
|
pbTurnTowardEvent($game_player,event)
|
|
Kernel.pbMoveTowardPlayer(event)
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Loads Pokémon/item/trainer graphics
|
|
################################################################################
|
|
def pbPokemonBitmapFile(species, shiny, back=false) # Unused
|
|
if shiny
|
|
# Load shiny bitmap
|
|
ret=sprintf("Graphics/Battlers/%ss%s",getConstantName(PBSpecies,species),back ? "b" : "") rescue nil
|
|
if !pbResolveBitmap(ret)
|
|
ret=sprintf("Graphics/Battlers/%03ds%s",species,back ? "b" : "")
|
|
end
|
|
return ret
|
|
else
|
|
# Load normal bitmap
|
|
ret=sprintf("Graphics/Battlers/%s%s",getConstantName(PBSpecies,species),back ? "b" : "") rescue nil
|
|
if !pbResolveBitmap(ret)
|
|
ret=sprintf("Graphics/Battlers/%03d%s",species,back ? "b" : "")
|
|
end
|
|
return ret
|
|
end
|
|
end
|
|
|
|
def pbLoadPokemonBitmap(pokemon, back=false)
|
|
return pbLoadPokemonBitmapSpecies(pokemon,pokemon.species,back)
|
|
end
|
|
|
|
# Note: Returns an AnimatedBitmap, not a Bitmap
|
|
def pbLoadPokemonBitmapSpecies(pokemon, species, back=false)
|
|
ret=nil
|
|
if pokemon.isEgg?
|
|
bitmapFileName=sprintf("Graphics/Battlers/%segg",getConstantName(PBSpecies,species)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Battlers/%03degg",species)
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Battlers/egg")
|
|
end
|
|
end
|
|
bitmapFileName=pbResolveBitmap(bitmapFileName)
|
|
else
|
|
bitmapFileName=pbCheckPokemonBitmapFiles([species,back,
|
|
(pokemon.isFemale?),
|
|
pokemon.isShiny?,
|
|
(pokemon.form rescue 0),
|
|
(pokemon.isShadow? rescue false)])
|
|
# Alter bitmap if supported
|
|
alterBitmap=(MultipleForms.getFunction(species,"alterBitmap") rescue nil)
|
|
end
|
|
if bitmapFileName && alterBitmap
|
|
animatedBitmap=AnimatedBitmap.new(bitmapFileName)
|
|
copiedBitmap=animatedBitmap.copy
|
|
animatedBitmap.dispose
|
|
copiedBitmap.each {|bitmap|
|
|
alterBitmap.call(pokemon,bitmap)
|
|
}
|
|
ret=copiedBitmap
|
|
elsif bitmapFileName
|
|
ret=AnimatedBitmap.new(bitmapFileName)
|
|
end
|
|
return ret
|
|
end
|
|
|
|
# Note: Returns an AnimatedBitmap, not a Bitmap
|
|
def pbLoadSpeciesBitmap(species,female=false,form=0,shiny=false,shadow=false,back=false,egg=false)
|
|
ret=nil
|
|
if egg
|
|
bitmapFileName=sprintf("Graphics/Battlers/%segg",getConstantName(PBSpecies,species)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Battlers/%03degg",species)
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Battlers/egg")
|
|
end
|
|
end
|
|
bitmapFileName=pbResolveBitmap(bitmapFileName)
|
|
else
|
|
bitmapFileName=pbCheckPokemonBitmapFiles([species,back,female,shiny,form,shadow])
|
|
end
|
|
if bitmapFileName
|
|
ret=AnimatedBitmap.new(bitmapFileName)
|
|
end
|
|
return ret
|
|
end
|
|
|
|
def pbCheckPokemonBitmapFiles(params)
|
|
species=params[0]
|
|
back=params[1]
|
|
factors=[]
|
|
factors.push([5,params[5],false]) if params[5] && params[5]!=false # shadow
|
|
factors.push([2,params[2],false]) if params[2] && params[2]!=false # gender
|
|
factors.push([3,params[3],false]) if params[3] && params[3]!=false # shiny
|
|
factors.push([4,params[4].to_s,""]) if params[4] && params[4].to_s!="" &&
|
|
params[4].to_s!="0" # form
|
|
tshadow=false
|
|
tgender=false
|
|
tshiny=false
|
|
tform=""
|
|
for i in 0...2**factors.length
|
|
for j in 0...factors.length
|
|
case factors[j][0]
|
|
when 2 # gender
|
|
tgender=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
|
|
when 3 # shiny
|
|
tshiny=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
|
|
when 4 # form
|
|
tform=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
|
|
when 5 # shadow
|
|
tshadow=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
|
|
end
|
|
end
|
|
bitmapFileName=sprintf("Graphics/Battlers/%s%s%s%s%s%s",
|
|
getConstantName(PBSpecies,species),
|
|
tgender ? "f" : "",
|
|
tshiny ? "s" : "",
|
|
back ? "b" : "",
|
|
(tform!="" ? "_"+tform : ""),
|
|
tshadow ? "_shadow" : "") rescue nil
|
|
ret=pbResolveBitmap(bitmapFileName)
|
|
return ret if ret
|
|
bitmapFileName=sprintf("Graphics/Battlers/%03d%s%s%s%s%s",
|
|
species,
|
|
tgender ? "f" : "",
|
|
tshiny ? "s" : "",
|
|
back ? "b" : "",
|
|
(tform!="" ? "_"+tform : ""),
|
|
tshadow ? "_shadow" : "")
|
|
ret=pbResolveBitmap(bitmapFileName)
|
|
return ret if ret
|
|
end
|
|
return nil
|
|
end
|
|
|
|
def pbLoadPokemonIcon(pokemon)
|
|
return AnimatedBitmap.new(pbPokemonIconFile(pokemon)).deanimate
|
|
end
|
|
|
|
def pbPokemonIconFile(pokemon)
|
|
bitmapFileName=nil
|
|
bitmapFileName=pbCheckPokemonIconFiles([pokemon.species,
|
|
(pokemon.isFemale?),
|
|
pokemon.isShiny?,
|
|
(pokemon.form rescue 0),
|
|
(pokemon.isShadow? rescue false)],
|
|
pokemon.isEgg?)
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbCheckPokemonIconFiles(params,egg=false)
|
|
species=params[0]
|
|
if egg
|
|
bitmapFileName=sprintf("Graphics/Icons/icon%segg",getConstantName(PBSpecies,species)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Icons/icon%03degg",species)
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Icons/iconEgg")
|
|
end
|
|
end
|
|
return pbResolveBitmap(bitmapFileName)
|
|
else
|
|
factors=[]
|
|
factors.push([4,params[4],false]) if params[4] && params[4]!=false # shadow
|
|
factors.push([1,params[1],false]) if params[1] && params[1]!=false # gender
|
|
factors.push([2,params[2],false]) if params[2] && params[2]!=false # shiny
|
|
factors.push([3,params[3].to_s,""]) if params[3] && params[3].to_s!="" &&
|
|
params[3].to_s!="0" # form
|
|
tshadow=false
|
|
tgender=false
|
|
tshiny=false
|
|
tform=""
|
|
for i in 0...2**factors.length
|
|
for j in 0...factors.length
|
|
case factors[j][0]
|
|
when 1 # gender
|
|
tgender=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
|
|
when 2 # shiny
|
|
tshiny=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
|
|
when 3 # form
|
|
tform=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
|
|
when 4 # shadow
|
|
tshadow=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
|
|
end
|
|
end
|
|
bitmapFileName=sprintf("Graphics/Icons/icon%s%s%s%s%s",
|
|
getConstantName(PBSpecies,species),
|
|
tgender ? "f" : "",
|
|
tshiny ? "s" : "",
|
|
(tform!="" ? "_"+tform : ""),
|
|
tshadow ? "_shadow" : "") rescue nil
|
|
ret=pbResolveBitmap(bitmapFileName)
|
|
return ret if ret
|
|
bitmapFileName=sprintf("Graphics/Icons/icon%03d%s%s%s%s",
|
|
species,
|
|
tgender ? "f" : "",
|
|
tshiny ? "s" : "",
|
|
(tform!="" ? "_"+tform : ""),
|
|
tshadow ? "_shadow" : "")
|
|
ret=pbResolveBitmap(bitmapFileName)
|
|
return ret if ret
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
def pbPokemonFootprintFile(pokemon) # Used by the Pokédex
|
|
return nil if !pokemon
|
|
if pokemon.is_a?(Numeric)
|
|
bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%s",getConstantName(PBSpecies,pokemon)) rescue nil
|
|
bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%03d",pokemon) if !pbResolveBitmap(bitmapFileName)
|
|
else
|
|
bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%s_%d",getConstantName(PBSpecies,pokemon.species),(pokemon.form rescue 0)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%03d_%d",pokemon.species,(pokemon.form rescue 0)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%s",getConstantName(PBSpecies,pokemon.species)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Icons/Footprints/footprint%03d",pokemon.species)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return pbResolveBitmap(bitmapFileName)
|
|
end
|
|
|
|
def pbItemIconFile(item)
|
|
return nil if !item
|
|
bitmapFileName=nil
|
|
if item==0
|
|
bitmapFileName=sprintf("Graphics/Icons/itemBack")
|
|
else
|
|
bitmapFileName=sprintf("Graphics/Icons/item%s",getConstantName(PBItems,item)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Icons/item%03d",item)
|
|
end
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbMailBackFile(item)
|
|
return nil if !item
|
|
bitmapFileName=sprintf("Graphics/Pictures/mail%s",getConstantName(PBItems,item)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Pictures/mail%03d",item)
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbTrainerCharFile(type)
|
|
return nil if !type
|
|
bitmapFileName=sprintf("Graphics/Characters/trchar%s",getConstantName(PBTrainers,type)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Characters/trchar%03d",type)
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbTrainerCharNameFile(type)
|
|
return nil if !type
|
|
bitmapFileName=sprintf("trchar%s",getConstantName(PBTrainers,type)) rescue nil
|
|
if !pbResolveBitmap(sprintf("Graphics/Characters/"+bitmapFileName))
|
|
bitmapFileName=sprintf("trchar%03d",type)
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbTrainerHeadFile(type)
|
|
return nil if !type
|
|
bitmapFileName=sprintf("Graphics/Pictures/mapPlayer%s",getConstantName(PBTrainers,type)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Pictures/mapPlayer%03d",type)
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbPlayerHeadFile(type)
|
|
return nil if !type
|
|
outfit=$Trainer ? $Trainer.outfit : 0
|
|
bitmapFileName=sprintf("Graphics/Pictures/mapPlayer%s_%d",
|
|
getConstantName(PBTrainers,type),outfit) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Pictures/mapPlayer%03d_%d",type,outfit)
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=pbTrainerHeadFile(type)
|
|
end
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbTrainerSpriteFile(type)
|
|
return nil if !type
|
|
bitmapFileName=sprintf("Graphics/Characters/trainer%s",getConstantName(PBTrainers,type)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Characters/trainer%03d",type)
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbTrainerSpriteBackFile(type)
|
|
return nil if !type
|
|
bitmapFileName=sprintf("Graphics/Characters/trback%s",getConstantName(PBTrainers,type)) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Characters/trback%03d",type)
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbPlayerSpriteFile(type)
|
|
return nil if !type
|
|
outfit=$Trainer ? $Trainer.outfit : 0
|
|
bitmapFileName=sprintf("Graphics/Characters/trainer%s_%d",
|
|
getConstantName(PBTrainers,type),outfit) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Characters/trainer%03d_%d",type,outfit)
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=pbTrainerSpriteFile(type)
|
|
end
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
def pbPlayerSpriteBackFile(type)
|
|
return nil if !type
|
|
outfit=$Trainer ? $Trainer.outfit : 0
|
|
bitmapFileName=sprintf("Graphics/Characters/trback%s_%d",
|
|
getConstantName(PBTrainers,type),outfit) rescue nil
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=sprintf("Graphics/Characters/trback%03d_%d",type,outfit)
|
|
if !pbResolveBitmap(bitmapFileName)
|
|
bitmapFileName=pbTrainerSpriteBackFile(type)
|
|
end
|
|
end
|
|
return bitmapFileName
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Loads music and sound effects
|
|
################################################################################
|
|
def pbResolveAudioSE(file)
|
|
return nil if !file
|
|
if RTP.exists?("Audio/SE/"+file,["",".wav",".mp3",".ogg"])
|
|
return RTP.getPath("Audio/SE/"+file,["",".wav",".mp3",".ogg"])
|
|
end
|
|
return nil
|
|
end
|
|
|
|
def pbCryFrameLength(pokemon,pitch=nil)
|
|
return 0 if !pokemon
|
|
pitch=100 if !pitch
|
|
pitch=pitch.to_f/100
|
|
return 0 if pitch<=0
|
|
playtime=0.0
|
|
if pokemon.is_a?(Numeric)
|
|
pkmnwav=pbResolveAudioSE(pbCryFile(pokemon))
|
|
playtime=getPlayTime(pkmnwav) if pkmnwav
|
|
elsif !pokemon.isEgg?
|
|
if pokemon.respond_to?("chatter") && pokemon.chatter
|
|
playtime=pokemon.chatter.time
|
|
pitch=1.0
|
|
else
|
|
pkmnwav=pbResolveAudioSE(pbCryFile(pokemon))
|
|
playtime=getPlayTime(pkmnwav) if pkmnwav
|
|
end
|
|
end
|
|
playtime/=pitch # sound is lengthened the lower the pitch
|
|
# 4 is added to provide a buffer between sounds
|
|
return (playtime*Graphics.frame_rate).ceil+4
|
|
end
|
|
|
|
def pbPlayCry(pokemon,volume=90,pitch=nil)
|
|
return if !pokemon
|
|
if pokemon.is_a?(Numeric)
|
|
pkmnwav=pbCryFile(pokemon)
|
|
if pkmnwav
|
|
pbSEPlay(RPG::AudioFile.new(pkmnwav,volume,pitch ? pitch : 100)) rescue nil
|
|
end
|
|
elsif !pokemon.isEgg?
|
|
if pokemon.respond_to?("chatter") && pokemon.chatter
|
|
pokemon.chatter.play
|
|
else
|
|
pkmnwav=pbCryFile(pokemon)
|
|
if pkmnwav
|
|
pbSEPlay(RPG::AudioFile.new(pkmnwav,volume,
|
|
pitch ? pitch : (pokemon.hp*25/pokemon.totalhp)+75)) rescue nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def pbCryFile(pokemon)
|
|
return nil if !pokemon
|
|
if pokemon.is_a?(Numeric)
|
|
filename=sprintf("Cries/%sCry",getConstantName(PBSpecies,pokemon)) rescue nil
|
|
filename=sprintf("Cries/%03dCry",pokemon) if !pbResolveAudioSE(filename)
|
|
return filename if pbResolveAudioSE(filename)
|
|
elsif !pokemon.isEgg?
|
|
filename=sprintf("Cries/%sCry_%d",getConstantName(PBSpecies,pokemon.species),(pokemon.form rescue 0)) rescue nil
|
|
filename=sprintf("Cries/%03dCry_%d",pokemon.species,(pokemon.form rescue 0)) if !pbResolveAudioSE(filename)
|
|
if !pbResolveAudioSE(filename)
|
|
filename=sprintf("Cries/%sCry",getConstantName(PBSpecies,pokemon.species)) rescue nil
|
|
end
|
|
filename=sprintf("Cries/%03dCry",pokemon.species) if !pbResolveAudioSE(filename)
|
|
return filename if pbResolveAudioSE(filename)
|
|
end
|
|
return nil
|
|
end
|
|
|
|
def pbGetWildBattleBGM(species)
|
|
if $PokemonGlobal.nextBattleBGM
|
|
return $PokemonGlobal.nextBattleBGM.clone
|
|
end
|
|
ret=nil
|
|
if !ret && $game_map
|
|
# Check map-specific metadata
|
|
music=pbGetMetadata($game_map.map_id,MetadataMapWildBattleBGM)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
if !ret
|
|
# Check global metadata
|
|
music=pbGetMetadata(0,MetadataWildBattleBGM)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
ret=pbStringToAudioFile("BT-Wild.mp3") if !ret
|
|
return ret
|
|
end
|
|
|
|
def pbGetWildVictoryME
|
|
if $PokemonGlobal.nextBattleME
|
|
return $PokemonGlobal.nextBattleME.clone
|
|
end
|
|
ret=nil
|
|
if !ret && $game_map
|
|
# Check map-specific metadata
|
|
music=pbGetMetadata($game_map.map_id,MetadataMapWildVictoryME)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
if !ret
|
|
# Check global metadata
|
|
music=pbGetMetadata(0,MetadataWildVictoryME)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
ret=pbStringToAudioFile("001-Victory01") if !ret
|
|
ret.name="../../Audio/ME/"+ret.name
|
|
return ret
|
|
end
|
|
|
|
def pbPlayTrainerIntroME(trainertype)
|
|
pbRgssOpen("Data/trainertypes.dat","rb"){|f|
|
|
trainertypes=Marshal.load(f)
|
|
if trainertypes[trainertype]
|
|
bgm=trainertypes[trainertype][6]
|
|
if bgm && bgm!=""
|
|
bgm=pbStringToAudioFile(bgm)
|
|
pbMEPlay(bgm)
|
|
return
|
|
end
|
|
end
|
|
}
|
|
end
|
|
|
|
def pbGetTrainerBattleBGM(trainer) # can be a PokeBattle_Trainer or an array of PokeBattle_Trainer
|
|
if $PokemonGlobal.nextBattleBGM
|
|
return $PokemonGlobal.nextBattleBGM.clone
|
|
end
|
|
music=nil
|
|
pbRgssOpen("Data/trainertypes.dat","rb"){|f|
|
|
trainertypes=Marshal.load(f)
|
|
if !trainer.is_a?(Array)
|
|
trainerarray=[trainer]
|
|
else
|
|
trainerarray=trainer
|
|
end
|
|
for i in 0...trainerarray.length
|
|
trainertype=trainerarray[i].trainertype
|
|
if trainertypes[trainertype]
|
|
music=trainertypes[trainertype][4]
|
|
end
|
|
end
|
|
}
|
|
ret=nil
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
if !ret && $game_map
|
|
# Check map-specific metadata
|
|
music=pbGetMetadata($game_map.map_id,MetadataMapTrainerBattleBGM)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
if !ret
|
|
# Check global metadata
|
|
music=pbGetMetadata(0,MetadataTrainerBattleBGM)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
ret=pbStringToAudioFile("005-Boss01") if !ret
|
|
return ret
|
|
end
|
|
|
|
def pbGetTrainerBattleBGMFromType(trainertype)
|
|
if $PokemonGlobal.nextBattleBGM
|
|
return $PokemonGlobal.nextBattleBGM.clone
|
|
end
|
|
music=nil
|
|
pbRgssOpen("Data/trainertypes.dat","rb"){|f|
|
|
trainertypes=Marshal.load(f)
|
|
if trainertypes[trainertype]
|
|
music=trainertypes[trainertype][4]
|
|
end
|
|
}
|
|
ret=nil
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
if !ret && $game_map
|
|
# Check map-specific metadata
|
|
music=pbGetMetadata($game_map.map_id,MetadataMapTrainerBattleBGM)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
if !ret
|
|
# Check global metadata
|
|
music=pbGetMetadata(0,MetadataTrainerBattleBGM)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
ret=pbStringToAudioFile("005-Boss01") if !ret
|
|
return ret
|
|
end
|
|
|
|
def pbGetTrainerVictoryME(trainer) # can be a PokeBattle_Trainer or an array of PokeBattle_Trainer
|
|
if $PokemonGlobal.nextBattleME
|
|
return $PokemonGlobal.nextBattleME.clone
|
|
end
|
|
music=nil
|
|
pbRgssOpen("Data/trainertypes.dat","rb"){|f|
|
|
trainertypes=Marshal.load(f)
|
|
if !trainer.is_a?(Array)
|
|
trainerarray=[trainer]
|
|
else
|
|
trainerarray=trainer
|
|
end
|
|
for i in 0...trainerarray.length
|
|
trainertype=trainerarray[i].trainertype
|
|
if trainertypes[trainertype]
|
|
music=trainertypes[trainertype][5]
|
|
end
|
|
end
|
|
}
|
|
ret=nil
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
if !ret && $game_map
|
|
# Check map-specific metadata
|
|
music=pbGetMetadata($game_map.map_id,MetadataMapTrainerVictoryME)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
if !ret
|
|
# Check global metadata
|
|
music=pbGetMetadata(0,MetadataTrainerVictoryME)
|
|
if music && music!=""
|
|
ret=pbStringToAudioFile(music)
|
|
end
|
|
end
|
|
ret=pbStringToAudioFile("001-Victory01") if !ret
|
|
ret.name="../../Audio/ME/"+ret.name
|
|
return ret
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Creating and storing Pokémon
|
|
################################################################################
|
|
# For demonstration purposes only, not to be used in a real game.
|
|
def pbCreatePokemon
|
|
party=[]
|
|
species=[:PIKACHU,:PIDGEOTTO,:KADABRA,:GYARADOS,:DIGLETT,:CHANSEY]
|
|
for id in species
|
|
party.push(getConst(PBSpecies,id)) if hasConst?(PBSpecies,id)
|
|
end
|
|
# Species IDs of the Pokémon to be created
|
|
for i in 0...party.length
|
|
species=party[i]
|
|
# Generate Pokémon with species and level 20
|
|
$Trainer.party[i]=PokeBattle_Pokemon.new(species,20,$Trainer)
|
|
$Trainer.seen[species]=true # Set this species to seen and owned
|
|
$Trainer.owned[species]=true
|
|
pbSeenForm($Trainer.party[i])
|
|
end
|
|
$Trainer.party[1].pbLearnMove(:FLY)
|
|
$Trainer.party[2].pbLearnMove(:FLASH)
|
|
$Trainer.party[2].pbLearnMove(:TELEPORT)
|
|
$Trainer.party[3].pbLearnMove(:SURF)
|
|
$Trainer.party[3].pbLearnMove(:DIVE)
|
|
$Trainer.party[3].pbLearnMove(:WATERFALL)
|
|
$Trainer.party[4].pbLearnMove(:DIG)
|
|
$Trainer.party[4].pbLearnMove(:CUT)
|
|
$Trainer.party[4].pbLearnMove(:HEADBUTT)
|
|
$Trainer.party[4].pbLearnMove(:ROCKSMASH)
|
|
$Trainer.party[5].pbLearnMove(:SOFTBOILED)
|
|
$Trainer.party[5].pbLearnMove(:STRENGTH)
|
|
$Trainer.party[5].pbLearnMove(:SWEETSCENT)
|
|
for i in 0...party.length
|
|
$Trainer.party[i].pbRecordFirstMoves
|
|
end
|
|
end
|
|
|
|
def pbBoxesFull?
|
|
return !$Trainer || ($Trainer.party.length==6 && $PokemonStorage.full?)
|
|
end
|
|
|
|
def pbNickname(pokemon)
|
|
speciesname=PBSpecies.getName(pokemon.species)
|
|
if Kernel.pbConfirmMessage(_INTL("Would you like to give a nickname to {1}?",speciesname))
|
|
helptext=_INTL("{1}'s nickname?",speciesname)
|
|
newname=pbEnterPokemonName(helptext,0,10,"",pokemon)
|
|
pokemon.name=newname if newname!=""
|
|
end
|
|
end
|
|
|
|
def pbStorePokemon(pokemon)
|
|
if pbBoxesFull?
|
|
Kernel.pbMessage(_INTL("There's no more room for Pokémon!\1"))
|
|
Kernel.pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
|
|
return
|
|
end
|
|
pokemon.pbRecordFirstMoves
|
|
if $Trainer.party.length<6
|
|
$Trainer.party[$Trainer.party.length]=pokemon
|
|
else
|
|
oldcurbox=$PokemonStorage.currentBox
|
|
storedbox=$PokemonStorage.pbStoreCaught(pokemon)
|
|
curboxname=$PokemonStorage[oldcurbox].name
|
|
boxname=$PokemonStorage[storedbox].name
|
|
creator=nil
|
|
creator=Kernel.pbGetStorageCreator if $PokemonGlobal.seenStorageCreator
|
|
if storedbox!=oldcurbox
|
|
if creator
|
|
Kernel.pbMessage(_INTL("Box \"{1}\" on {2}'s PC was full.\1",curboxname,creator))
|
|
else
|
|
Kernel.pbMessage(_INTL("Box \"{1}\" on someone's PC was full.\1",curboxname))
|
|
end
|
|
Kernel.pbMessage(_INTL("{1} was transferred to box \"{2}.\"",pokemon.name,boxname))
|
|
else
|
|
if creator
|
|
Kernel.pbMessage(_INTL("{1} was transferred to {2}'s PC.\1",pokemon.name,creator))
|
|
else
|
|
Kernel.pbMessage(_INTL("{1} was transferred to someone's PC.\1",pokemon.name))
|
|
end
|
|
Kernel.pbMessage(_INTL("It was stored in box \"{1}.\"",boxname))
|
|
end
|
|
end
|
|
end
|
|
|
|
def pbNicknameAndStore(pokemon)
|
|
if pbBoxesFull?
|
|
Kernel.pbMessage(_INTL("There's no more room for Pokémon!\1"))
|
|
Kernel.pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
|
|
return
|
|
end
|
|
$Trainer.seen[pokemon.species]=true
|
|
$Trainer.owned[pokemon.species]=true
|
|
pbNickname(pokemon)
|
|
pbStorePokemon(pokemon)
|
|
end
|
|
|
|
def pbAddPokemon(pokemon,level=nil,seeform=true)
|
|
return if !pokemon || !$Trainer
|
|
if pbBoxesFull?
|
|
Kernel.pbMessage(_INTL("There's no more room for Pokémon!\1"))
|
|
Kernel.pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
|
|
return false
|
|
end
|
|
if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
|
|
pokemon=getID(PBSpecies,pokemon)
|
|
end
|
|
if pokemon.is_a?(Integer) && level.is_a?(Integer)
|
|
pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
|
|
end
|
|
speciesname=PBSpecies.getName(pokemon.species)
|
|
if $Trainer.party.length==0
|
|
pbMEPlay("fffirstpokemon")
|
|
Kernel.pbMessage(_INTL("{1} obtained {2}!\1",$Trainer.name,speciesname))
|
|
else
|
|
pbMEPlay("PokemonGet")
|
|
Kernel.pbMessage(_INTL("{1} obtained {2}!\1",$Trainer.name,speciesname))
|
|
end
|
|
pbNicknameAndStore(pokemon)
|
|
pbSeenForm(pokemon) if seeform
|
|
return true
|
|
end
|
|
|
|
def pbAddPokemonSilent(pokemon,level=nil,seeform=true)
|
|
return false if !pokemon || pbBoxesFull? || !$Trainer
|
|
if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
|
|
pokemon=getID(PBSpecies,pokemon)
|
|
end
|
|
if pokemon.is_a?(Integer) && level.is_a?(Integer)
|
|
pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
|
|
end
|
|
$Trainer.seen[pokemon.species]=true
|
|
$Trainer.owned[pokemon.species]=true
|
|
pbSeenForm(pokemon) if seeform
|
|
pokemon.pbRecordFirstMoves
|
|
if $Trainer.party.length<6
|
|
$Trainer.party[$Trainer.party.length]=pokemon
|
|
else
|
|
$PokemonStorage.pbStoreCaught(pokemon)
|
|
end
|
|
return true
|
|
end
|
|
|
|
def pbAddToParty(pokemon,level=nil,seeform=true)
|
|
return false if !pokemon || !$Trainer || $Trainer.party.length>=6
|
|
if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
|
|
pokemon=getID(PBSpecies,pokemon)
|
|
end
|
|
if pokemon.is_a?(Integer) && level.is_a?(Integer)
|
|
pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
|
|
end
|
|
speciesname=PBSpecies.getName(pokemon.species)
|
|
Kernel.pbMessage(_INTL("{1} obtained {2}!\\se[PokemonGet]\1",$Trainer.name,speciesname))
|
|
pbNicknameAndStore(pokemon)
|
|
pbSeenForm(pokemon) if seeform
|
|
return true
|
|
end
|
|
|
|
def pbAddToPartySilent(pokemon,level=nil,seeform=true)
|
|
return false if !pokemon || !$Trainer || $Trainer.party.length>=6
|
|
if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
|
|
pokemon=getID(PBSpecies,pokemon)
|
|
end
|
|
if pokemon.is_a?(Integer) && level.is_a?(Integer)
|
|
pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
|
|
end
|
|
$Trainer.seen[pokemon.species]=true
|
|
$Trainer.owned[pokemon.species]=true
|
|
pbSeenForm(pokemon) if seeform
|
|
pokemon.pbRecordFirstMoves
|
|
$Trainer.party[$Trainer.party.length]=pokemon
|
|
return true
|
|
end
|
|
|
|
def pbAddForeignPokemon(pokemon,level=nil,ownerName=nil,nickname=nil,ownerGender=0,seeform=true)
|
|
return false if !pokemon || !$Trainer || $Trainer.party.length>=6
|
|
if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
|
|
pokemon=getID(PBSpecies,pokemon)
|
|
end
|
|
if pokemon.is_a?(Integer) && level.is_a?(Integer)
|
|
pokemon=PokeBattle_Pokemon.new(pokemon,level,$Trainer)
|
|
end
|
|
# Set original trainer to a foreign one (if ID isn't already foreign)
|
|
if pokemon.trainerID==$Trainer.id
|
|
pokemon.trainerID=$Trainer.getForeignID
|
|
pokemon.ot=ownerName if ownerName && ownerName!=""
|
|
pokemon.otgender=ownerGender
|
|
end
|
|
# Set nickname
|
|
pokemon.name=nickname[0,10] if nickname && nickname!=""
|
|
# Recalculate stats
|
|
pokemon.calcStats
|
|
if ownerName
|
|
Kernel.pbMessage(_INTL("{1} received a Pokémon from {2}.\\se[PokemonGet]\1",$Trainer.name,ownerName))
|
|
else
|
|
Kernel.pbMessage(_INTL("{1} received a Pokémon.\\se[PokemonGet]\1",$Trainer.name))
|
|
end
|
|
pbStorePokemon(pokemon)
|
|
$Trainer.seen[pokemon.species]=true
|
|
$Trainer.owned[pokemon.species]=true
|
|
pbSeenForm(pokemon) if seeform
|
|
return true
|
|
end
|
|
|
|
def pbGenerateEgg(pokemon,text="")
|
|
return false if !pokemon || !$Trainer || $Trainer.party.length>=6
|
|
if pokemon.is_a?(String) || pokemon.is_a?(Symbol)
|
|
pokemon=getID(PBSpecies,pokemon)
|
|
end
|
|
if pokemon.is_a?(Integer)
|
|
pokemon=PokeBattle_Pokemon.new(pokemon,EGGINITIALLEVEL,$Trainer)
|
|
end
|
|
# Get egg steps
|
|
dexdata=pbOpenDexData
|
|
pbDexDataOffset(dexdata,pokemon.species,21)
|
|
eggsteps=dexdata.fgetw
|
|
dexdata.close
|
|
# Set egg's details
|
|
pokemon.name=_INTL("Egg")
|
|
pokemon.eggsteps=eggsteps
|
|
pokemon.obtainText=text
|
|
pokemon.calcStats
|
|
# Add egg to party
|
|
$Trainer.party[$Trainer.party.length]=pokemon
|
|
return true
|
|
end
|
|
|
|
def pbRemovePokemonAt(index)
|
|
return false if index<0 || !$Trainer || index>=$Trainer.party.length
|
|
haveAble=false
|
|
for i in 0...$Trainer.party.length
|
|
next if i==index
|
|
haveAble=true if $Trainer.party[i].hp>0 && !$Trainer.party[i].isEgg?
|
|
end
|
|
return false if !haveAble
|
|
$Trainer.party.delete_at(index)
|
|
return true
|
|
end
|
|
|
|
def pbSeenForm(poke,gender=0,form=0)
|
|
$Trainer.formseen=[] if !$Trainer.formseen
|
|
$Trainer.formlastseen=[] if !$Trainer.formlastseen
|
|
if poke.is_a?(String) || poke.is_a?(Symbol)
|
|
poke=getID(PBSpecies,poke)
|
|
end
|
|
if poke.is_a?(PokeBattle_Pokemon)
|
|
gender=poke.gender
|
|
form=(poke.form rescue 0)
|
|
species=poke.species
|
|
else
|
|
species=poke
|
|
end
|
|
return if !species || species<=0
|
|
gender=0 if gender>1
|
|
formnames=pbGetMessage(MessageTypes::FormNames,species)
|
|
form=0 if !formnames || formnames=="" #Emily 7-23
|
|
$Trainer.formseen[species]=[[],[]] if !$Trainer.formseen[species]
|
|
$Trainer.formseen[species][gender][form]=true
|
|
$Trainer.formlastseen[species]=[] if !$Trainer.formlastseen[species]
|
|
$Trainer.formlastseen[species]=[gender,form] if $Trainer.formlastseen[species]==[]
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Analysing Pokémon
|
|
################################################################################
|
|
# Heals all Pokémon in the party.
|
|
def pbHealAll
|
|
return if !$Trainer
|
|
for i in $Trainer.party
|
|
i.heal
|
|
end
|
|
end
|
|
|
|
# Returns the first unfainted, non-egg Pokémon in the player's party.
|
|
def pbFirstAblePokemon(variableNumber)
|
|
for i in 0...$Trainer.party.length
|
|
p=$Trainer.party[i]
|
|
if p && !p.isEgg? && p.hp>0
|
|
pbSet(variableNumber,i)
|
|
return $Trainer.party[i]
|
|
end
|
|
end
|
|
pbSet(variableNumber,-1)
|
|
return nil
|
|
end
|
|
|
|
# Checks whether the player would still have an unfainted Pokémon if the
|
|
# Pokémon given by _pokemonIndex_ were removed from the party.
|
|
def pbCheckAble(pokemonIndex)
|
|
for i in 0...$Trainer.party.length
|
|
p=$Trainer.party[i]
|
|
next if i==pokemonIndex
|
|
return true if p && !p.isEgg? && p.hp>0
|
|
end
|
|
return false
|
|
end
|
|
|
|
# Returns true if there are no usable Pokémon in the player's party.
|
|
def pbAllFainted
|
|
for i in $Trainer.party
|
|
return false if !i.isEgg? && i.hp>0
|
|
end
|
|
return true
|
|
end
|
|
|
|
def pbBalancedLevel(party)
|
|
return 1 if party.length==0
|
|
# Calculate the mean of all levels
|
|
sum=0
|
|
party.each{|p| sum+=p.level }
|
|
return 1 if sum==0
|
|
average=sum.to_f/party.length.to_f
|
|
# Calculate the standard deviation
|
|
varianceTimesN=0
|
|
for i in 0...party.length
|
|
deviation=party[i].level-average
|
|
varianceTimesN+=deviation*deviation
|
|
end
|
|
# Note: This is the "population" standard deviation calculation, since no
|
|
# sample is being taken
|
|
stdev=Math.sqrt(varianceTimesN/party.length)
|
|
mean=0
|
|
weights=[]
|
|
# Skew weights according to standard deviation
|
|
for i in 0...party.length
|
|
weight=party[i].level.to_f/sum.to_f
|
|
if weight<0.5
|
|
weight-=(stdev/PBExperience::MAXLEVEL.to_f)
|
|
weight=0.001 if weight<=0.001
|
|
else
|
|
weight+=(stdev/PBExperience::MAXLEVEL.to_f)
|
|
weight=0.999 if weight>=0.999
|
|
end
|
|
weights.push(weight)
|
|
end
|
|
weightSum=0
|
|
weights.each{|weight| weightSum+=weight }
|
|
# Calculate the weighted mean, assigning each weight to each level's
|
|
# contribution to the sum
|
|
for i in 0...party.length
|
|
mean+=party[i].level*weights[i]
|
|
end
|
|
mean/=weightSum
|
|
# Round to nearest number
|
|
mean=mean.round
|
|
# Adjust level to minimum
|
|
mean=1 if mean<1
|
|
# Add 2 to the mean to challenge the player
|
|
mean+=2
|
|
# Adjust level to maximum
|
|
mean=PBExperience::MAXLEVEL if mean>PBExperience::MAXLEVEL
|
|
return mean
|
|
end
|
|
|
|
# Returns the Pokémon's size in millimeters.
|
|
def pbSize(pokemon)
|
|
dexdata=pbOpenDexData
|
|
pbDexDataOffset(dexdata,pokemon.species,33)
|
|
baseheight=dexdata.fgetw # Gets the base height in tenths of a meter
|
|
dexdata.close
|
|
hpiv=pokemon.iv[0]&15
|
|
ativ=pokemon.iv[1]&15
|
|
dfiv=pokemon.iv[2]&15
|
|
spiv=pokemon.iv[3]&15
|
|
saiv=pokemon.iv[4]&15
|
|
sdiv=pokemon.iv[5]&15
|
|
m=pokemon.personalID&0xFF
|
|
n=(pokemon.personalID>>8)&0xFF
|
|
s=(((ativ^dfiv)*hpiv)^m)*256+(((saiv^sdiv)*spiv)^n)
|
|
xyz=[]
|
|
if s<10
|
|
xyz=[290,1,0]
|
|
elsif s<110
|
|
xyz=[300,1,10]
|
|
elsif s<310
|
|
xyz=[400,2,110]
|
|
elsif s<710
|
|
xyz=[500,4,310]
|
|
elsif s<2710
|
|
xyz=[600,20,710]
|
|
elsif s<7710
|
|
xyz=[700,50,2710]
|
|
elsif s<17710
|
|
xyz=[800,100,7710]
|
|
elsif s<32710
|
|
xyz=[900,150,17710]
|
|
elsif s<47710
|
|
xyz=[1000,150,32710]
|
|
elsif s<57710
|
|
xyz=[1100,100,47710]
|
|
elsif s<62710
|
|
xyz=[1200,50,57710]
|
|
elsif s<64710
|
|
xyz=[1300,20,62710]
|
|
elsif s<65210
|
|
xyz=[1400,5,64710]
|
|
elsif s<65410
|
|
xyz=[1500,2,65210]
|
|
else
|
|
xyz=[1700,1,65510]
|
|
end
|
|
return (((s-xyz[2])/xyz[1]+xyz[0]).floor*baseheight/10).floor
|
|
end
|
|
|
|
# Returns true if the given species can be legitimately obtained as an egg.
|
|
def pbHasEgg?(species)
|
|
if species.is_a?(String) || species.is_a?(Symbol)
|
|
species=getID(PBSpecies,species)
|
|
end
|
|
evospecies=pbGetEvolvedFormData(species)
|
|
compatspecies=(evospecies && evospecies[0]) ? evospecies[0][2] : species
|
|
dexdata=pbOpenDexData
|
|
pbDexDataOffset(dexdata,compatspecies,31)
|
|
compat1=dexdata.fgetb # Get egg group 1 of this species
|
|
compat2=dexdata.fgetb # Get egg group 2 of this species
|
|
dexdata.close
|
|
return false if isConst?(compat1,PBEggGroups,:Ditto) ||
|
|
isConst?(compat1,PBEggGroups,:Undiscovered) ||
|
|
isConst?(compat2,PBEggGroups,:Ditto) ||
|
|
isConst?(compat2,PBEggGroups,:Undiscovered)
|
|
baby=pbGetBabySpecies(species)
|
|
return true if species==baby # Is a basic species
|
|
baby=pbGetBabySpecies(species,0,0)
|
|
return true if species==baby # Is an egg species without incense
|
|
return false
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Look through Pokémon in storage, choose a Pokémon in the party
|
|
################################################################################
|
|
# Yields every Pokémon/egg in storage in turn.
|
|
def pbEachPokemon
|
|
for i in -1...$PokemonStorage.maxBoxes
|
|
for j in 0...$PokemonStorage.maxPokemon(i)
|
|
poke=$PokemonStorage[i][j]
|
|
yield(poke,i) if poke
|
|
end
|
|
end
|
|
end
|
|
|
|
# Yields every Pokémon in storage in turn.
|
|
def pbEachNonEggPokemon
|
|
pbEachPokemon{|pokemon,box|
|
|
yield(pokemon,box) if !pokemon.isEgg?
|
|
}
|
|
end
|
|
|
|
# Choose a Pokémon/egg from the party.
|
|
# Stores result in variable _variableNumber_ and the chosen Pokémon's name in
|
|
# variable _nameVarNumber_; result is -1 if no Pokémon was chosen
|
|
def pbChoosePokemon(variableNumber,nameVarNumber,ableProc=nil, allowIneligible=false)
|
|
chosen=0
|
|
pbFadeOutIn(99999){
|
|
scene=PokemonScreen_Scene.new
|
|
screen=PokemonScreen.new(scene,$Trainer.party)
|
|
if ableProc
|
|
chosen=screen.pbChooseAblePokemon(ableProc,allowIneligible)
|
|
else
|
|
screen.pbStartScene(_INTL("Choose a Pokémon."),false)
|
|
chosen=screen.pbChoosePokemon
|
|
screen.pbEndScene
|
|
end
|
|
}
|
|
pbSet(variableNumber,chosen)
|
|
if chosen>=0
|
|
pbSet(nameVarNumber,$Trainer.party[chosen].name)
|
|
else
|
|
pbSet(nameVarNumber,"")
|
|
end
|
|
end
|
|
|
|
def pbChooseNonEggPokemon(variableNumber,nameVarNumber)
|
|
pbChoosePokemon(variableNumber,nameVarNumber,proc {|poke|
|
|
!poke.isEgg?
|
|
})
|
|
end
|
|
|
|
def pbChooseAblePokemon(variableNumber,nameVarNumber)
|
|
pbChoosePokemon(variableNumber,nameVarNumber,proc {|poke|
|
|
!poke.isEgg? && poke.hp>0
|
|
})
|
|
end
|
|
|
|
def pbChoosePokemonForTrade(variableNumber,nameVarNumber,wanted)
|
|
pbChoosePokemon(variableNumber,nameVarNumber,proc {|poke|
|
|
if wanted.is_a?(String) || wanted.is_a?(Symbol)
|
|
wanted=getID(PBSpecies,wanted)
|
|
end
|
|
return !poke.isEgg? && !(poke.isShadow? rescue false) && poke.species==wanted
|
|
})
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Checks through the party for something
|
|
################################################################################
|
|
def pbHasSpecies?(species)
|
|
if species.is_a?(String) || species.is_a?(Symbol)
|
|
species=getID(PBSpecies,species)
|
|
end
|
|
for pokemon in $Trainer.party
|
|
next if pokemon.isEgg?
|
|
return true if pokemon.species==species
|
|
end
|
|
return false
|
|
end
|
|
|
|
def pbHasFatefulSpecies?(species)
|
|
if species.is_a?(String) || species.is_a?(Symbol)
|
|
species=getID(PBSpecies,species)
|
|
end
|
|
for pokemon in $Trainer.party
|
|
next if pokemon.isEgg?
|
|
return true if pokemon.species==species && pokemon.obtainMode==4
|
|
end
|
|
return false
|
|
end
|
|
|
|
def pbHasType?(type)
|
|
if type.is_a?(String) || type.is_a?(Symbol)
|
|
type=getID(PBTypes,type)
|
|
end
|
|
for pokemon in $Trainer.party
|
|
next if pokemon.isEgg?
|
|
return true if pokemon.hasType?(type)
|
|
end
|
|
return false
|
|
end
|
|
|
|
# Checks whether any Pokémon in the party knows the given move, and returns
|
|
# the index of that Pokémon, or nil if no Pokémon has that move.
|
|
def pbCheckMove(move)
|
|
move=getID(PBMoves,move)
|
|
return nil if !move || move<=0
|
|
for i in $Trainer.party
|
|
next if i.isEgg?
|
|
for j in i.moves
|
|
return i if j.id==move
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Regional and National Pokédexes
|
|
################################################################################
|
|
# Gets the Regional Pokédex number of the national species for the specified
|
|
# Regional Dex. The parameter "region" is zero-based. For example, if two
|
|
# regions are defined, they would each be specified as 0 and 1.
|
|
def pbGetRegionalNumber(region, nationalSpecies)
|
|
if nationalSpecies<=0 || nationalSpecies>PBSpecies.maxValue
|
|
# Return 0 if national species is outside range
|
|
return 0
|
|
end
|
|
pbRgssOpen("Data/regionals.dat","rb"){|f|
|
|
numRegions=f.fgetw
|
|
numDexDatas=f.fgetw
|
|
if region>=0 && region<numRegions
|
|
f.pos=4+region*numDexDatas*2
|
|
f.pos+=nationalSpecies*2
|
|
return f.fgetw
|
|
end
|
|
}
|
|
return 0
|
|
end
|
|
|
|
# Gets the National Pokédex number of the specified species and region. The
|
|
# parameter "region" is zero-based. For example, if two regions are defined,
|
|
# they would each be specified as 0 and 1.
|
|
def pbGetNationalNumber(region, regionalSpecies)
|
|
pbRgssOpen("Data/regionals.dat","rb"){|f|
|
|
numRegions=f.fgetw
|
|
numDexDatas=f.fgetw
|
|
if region>=0 && region<numRegions
|
|
f.pos=4+region*numDexDatas*2
|
|
# "i" specifies the national species
|
|
for i in 0...numDexDatas
|
|
regionalNum=f.fgetw
|
|
return i if regionalNum==regionalSpecies
|
|
end
|
|
end
|
|
}
|
|
return 0
|
|
end
|
|
|
|
# Gets an array of all national species within the given Regional Dex, sorted by
|
|
# Regional Dex number. The number of items in the array should be the
|
|
# number of species in the Regional Dex plus 1, since index 0 is considered
|
|
# to be empty. The parameter "region" is zero-based. For example, if two
|
|
# regions are defined, they would each be specified as 0 and 1.
|
|
def pbAllRegionalSpecies(region)
|
|
ret=[0]
|
|
pbRgssOpen("Data/regionals.dat","rb"){|f|
|
|
numRegions=f.fgetw
|
|
numDexDatas=f.fgetw
|
|
if region>=0 && region<numRegions
|
|
f.pos=4+region*numDexDatas*2
|
|
# "i" specifies the national species
|
|
for i in 0...numDexDatas
|
|
regionalNum=f.fgetw
|
|
ret[regionalNum]=i if regionalNum!=0
|
|
end
|
|
# Replace unspecified regional
|
|
# numbers with zeros
|
|
for i in 0...ret.length
|
|
ret[i]=0 if !ret[i]
|
|
end
|
|
end
|
|
}
|
|
return ret
|
|
end
|
|
|
|
# Gets the ID number for the current region based on the player's current
|
|
# position. Returns the value of "defaultRegion" (optional, default is -1) if
|
|
# no region was defined in the game's metadata. The ID numbers returned by
|
|
# this function depend on the current map's position metadata.
|
|
def pbGetCurrentRegion(defaultRegion=-1)
|
|
mappos=!$game_map ? nil : pbGetMetadata($game_map.map_id,MetadataMapPosition)
|
|
if !mappos
|
|
return defaultRegion # No region defined
|
|
else
|
|
return mappos[0]
|
|
end
|
|
end
|
|
|
|
# Decides which Dex lists are able to be viewed (i.e. they are unlocked and have
|
|
# at least 1 seen species in them), and saves all viable dex region numbers
|
|
# (National Dex comes after regional dexes).
|
|
# If the Dex list shown depends on the player's location, this just decides if
|
|
# a species in the current region has been seen - doesn't look at other regions.
|
|
# Here, just used to decide whether to show the Pokédex in the Pause menu.
|
|
def pbSetViableDexes
|
|
$PokemonGlobal.pokedexViable=[]
|
|
if DEXDEPENDSONLOCATION
|
|
region=pbGetCurrentRegion
|
|
region=-1 if region>=$PokemonGlobal.pokedexUnlocked.length-1
|
|
if $Trainer.pokedexSeen(region)>0
|
|
$PokemonGlobal.pokedexViable[0]=region
|
|
end
|
|
else
|
|
numDexes=$PokemonGlobal.pokedexUnlocked.length
|
|
case numDexes
|
|
when 1 # National Dex only
|
|
if $PokemonGlobal.pokedexUnlocked[0]
|
|
if $Trainer.pokedexSeen>0
|
|
$PokemonGlobal.pokedexViable.push(0)
|
|
end
|
|
end
|
|
else # Regional dexes + National Dex
|
|
for i in 0...numDexes
|
|
regionToCheck=(i==numDexes-1) ? -1 : i
|
|
if $PokemonGlobal.pokedexUnlocked[i]
|
|
if $Trainer.pokedexSeen(regionToCheck)>0
|
|
$PokemonGlobal.pokedexViable.push(i)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# Unlocks a Dex list. The National Dex is -1 here (or nil argument).
|
|
def pbUnlockDex(dex=-1)
|
|
index=dex
|
|
index=$PokemonGlobal.pokedexUnlocked.length-1 if index<0
|
|
index=$PokemonGlobal.pokedexUnlocked.length-1 if index>$PokemonGlobal.pokedexUnlocked.length-1
|
|
$PokemonGlobal.pokedexUnlocked[index]=true
|
|
end
|
|
|
|
# Locks a Dex list. The National Dex is -1 here (or nil argument).
|
|
def pbLockDex(dex=-1)
|
|
index=dex
|
|
index=$PokemonGlobal.pokedexUnlocked.length-1 if index<0
|
|
index=$PokemonGlobal.pokedexUnlocked.length-1 if index>$PokemonGlobal.pokedexUnlocked.length-1
|
|
$PokemonGlobal.pokedexUnlocked[index]=false
|
|
end
|
|
|
|
|
|
|
|
################################################################################
|
|
# Other utilities
|
|
################################################################################
|
|
def pbTextEntry(helptext,minlength,maxlength,variableNumber)
|
|
$game_variables[variableNumber]=pbEnterText(helptext,minlength,maxlength)
|
|
$game_map.need_refresh = true if $game_map
|
|
end
|
|
|
|
def pbMoveTutorAnnotations(move,movelist=nil)
|
|
ret=[]
|
|
for i in 0...6
|
|
ret[i]=nil
|
|
next if i>=$Trainer.party.length
|
|
found=false
|
|
for j in 0...4
|
|
if !$Trainer.party[i].isEgg? && $Trainer.party[i].moves[j].id==move
|
|
ret[i]=_INTL("LEARNED")
|
|
found=true
|
|
end
|
|
end
|
|
next if found
|
|
species=$Trainer.party[i].species
|
|
if !$Trainer.party[i].isEgg? && movelist && movelist.any?{|j| j==species }
|
|
# Checked data from movelist
|
|
ret[i]=_INTL("ABLE")
|
|
elsif !$Trainer.party[i].isEgg? && $Trainer.party[i].isCompatibleWithMove?(move)
|
|
# Checked data from PBS/tm.txt
|
|
ret[i]=_INTL("ABLE")
|
|
else
|
|
ret[i]=_INTL("NOT ABLE")
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
def pbMoveTutorChoose(move,movelist=nil,bymachine=false)
|
|
ret=false
|
|
if move.is_a?(String) || move.is_a?(Symbol)
|
|
move=getID(PBMoves,move)
|
|
end
|
|
if movelist!=nil && movelist.is_a?(Array)
|
|
for i in 0...movelist.length
|
|
if movelist[i].is_a?(String) || movelist[i].is_a?(Symbol)
|
|
movelist[i]=getID(PBSpecies,movelist[i])
|
|
end
|
|
end
|
|
end
|
|
pbFadeOutIn(99999){
|
|
scene=PokemonScreen_Scene.new
|
|
movename=PBMoves.getName(move)
|
|
screen=PokemonScreen.new(scene,$Trainer.party)
|
|
annot=pbMoveTutorAnnotations(move,movelist)
|
|
screen.pbStartScene(_INTL("Teach which Pokémon?"),false,annot)
|
|
loop do
|
|
chosen=screen.pbChoosePokemon
|
|
if chosen>=0
|
|
pokemon=$Trainer.party[chosen]
|
|
if pokemon.isEgg?
|
|
Kernel.pbMessage(_INTL("{1} can't be taught to an Egg.",movename))
|
|
elsif (pokemon.isShadow? rescue false)
|
|
Kernel.pbMessage(_INTL("Shadow Pokémon can't be taught any moves."))
|
|
elsif movelist && !movelist.any?{|j| j==pokemon.species }
|
|
Kernel.pbMessage(_INTL("{1} and {2} are not compatible.",pokemon.name,movename))
|
|
Kernel.pbMessage(_INTL("{1} can't be learned.",movename))
|
|
elsif !pokemon.isCompatibleWithMove?(move)
|
|
Kernel.pbMessage(_INTL("{1} and {2} are not compatible.",pokemon.name,movename))
|
|
Kernel.pbMessage(_INTL("{1} can't be learned.",movename))
|
|
else
|
|
if pbLearnMove(pokemon,move,false,bymachine)
|
|
ret=true
|
|
break
|
|
end
|
|
end
|
|
else
|
|
break
|
|
end
|
|
end
|
|
screen.pbEndScene
|
|
}
|
|
return ret # Returns whether the move was learned by a Pokemon
|
|
end
|
|
|
|
def pbChooseMove(pokemon,variableNumber,nameVarNumber)
|
|
return if !pokemon
|
|
ret=-1
|
|
pbFadeOutIn(99999){
|
|
scene=PokemonSummaryScene.new
|
|
screen=PokemonSummary.new(scene)
|
|
ret=screen.pbStartForgetScreen([pokemon],0,0)
|
|
}
|
|
$game_variables[variableNumber]=ret
|
|
if ret>=0
|
|
$game_variables[nameVarNumber]=PBMoves.getName(pokemon.moves[ret].id)
|
|
else
|
|
$game_variables[nameVarNumber]=""
|
|
end
|
|
$game_map.need_refresh = true if $game_map
|
|
end
|
|
|
|
# Opens the Pokémon screen
|
|
def pbPokemonScreen
|
|
return if !$Trainer
|
|
sscene=PokemonScreen_Scene.new
|
|
sscreen=PokemonScreen.new(sscene,$Trainer.party)
|
|
pbFadeOutIn(99999) { sscreen.pbPokemonScreen }
|
|
end
|
|
|
|
def pbSaveScreen
|
|
ret=false
|
|
scene=PokemonSaveScene.new
|
|
screen=PokemonSave.new(scene)
|
|
ret=screen.pbSaveScreen
|
|
return ret
|
|
end
|
|
|
|
def pbConvertItemToItem(variable,array)
|
|
item=pbGet(variable)
|
|
pbSet(variable,0)
|
|
for i in 0...(array.length/2)
|
|
if isConst?(item,PBItems,array[2*i])
|
|
pbSet(variable,getID(PBItems,array[2*i+1]))
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
def pbConvertItemToPokemon(variable,array)
|
|
item=pbGet(variable)
|
|
pbSet(variable,0)
|
|
for i in 0...(array.length/2)
|
|
if isConst?(item,PBItems,array[2*i])
|
|
pbSet(variable,getID(PBSpecies,array[2*i+1]))
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
class PokemonGlobalMetadata
|
|
attr_accessor :trainerRecording
|
|
end
|
|
|
|
|
|
|
|
def pbRecordTrainer
|
|
wave=pbRecord(nil,10)
|
|
if wave
|
|
$PokemonGlobal.trainerRecording=wave
|
|
return true
|
|
end
|
|
return false
|
|
end
|