#Not Important
All hail the wishmaker
- 910
- Posts
- 5
- Years
- He/Him
- Hoenn
- Seen Jul 22, 2023
This script adds a 3rd type to your pokémon (with the right PBS usage of course). Just make a new script section above main and below compiler and paste this and you'll get a 3rd type in your game!
Spoiler:
Code:
#===============================================================================
# * 3rd Type Script by #Not Important
#===============================================================================
#
# This script adds a 3rd type to your game. Here's how to define it in the PBS
# files:
#
# - In Pokemon.txt:
# Type3=[YOUR TYPE]
#
#
# Example:
# Type1=FIRE
# Type2=WATER
# Type3=GRASS
#
#===============================================================================
# That's it!
#===============================================================================
#
# Please give credits
#
#===============================================================================
# Compile Pokémon
#===============================================================================
def pbCompilePokemonData
# Free bytes: 0, 1, 59-75
# (Some bytes are used only by forms)
sections = []
requiredtypes = {
"Name" => [0,"s"],
"Kind" => [0,"s"],
"InternalName" => [0,"c"],
"Pokedex" => [0,"S"],
"Moves" => [0,"*uE",nil,PBMoves],
"Color" => [6,"e",PBColors],
"Type1" => [8,"e",PBTypes],
"BaseStats" => [10,"uuuuuu"],
"Rareness" => [16,"u"],
"Shape" => [17,"u"],
"GenderRate" => [18,"e",{"AlwaysMale"=>0,"FemaleOneEighth"=>31,
"Female25Percent"=>63,"Female50Percent"=>127,
"Female75Percent"=>191,"FemaleSevenEighths"=>223,
"AlwaysFemale"=>254,"Genderless"=>255}],
"Happiness" => [19,"u"],
"GrowthRate" => [20,"e",{"Medium"=>0,"MediumFast"=>0,"Erratic"=>1,
"Fluctuating"=>2,"Parabolic"=>3,"MediumSlow"=>3,
"Fast"=>4,"Slow"=>5}],
"StepsToHatch" => [21,"w"],
"EffortPoints" => [23,"uuuuuu"],
"Compatibility" => [31,"eg",PBEggGroups,PBEggGroups],
"Height" => [33,"f"],
"Weight" => [35,"f"],
"BaseEXP" => [38,"w"],
}
optionaltypes = {
"BattlerPlayerY" => [0,"i"],
"BattlerEnemyY" => [0,"i"],
"BattlerAltitude" => [0,"i"],
"EggMoves" => [0,"*E",PBMoves],
"FormName" => [0,"S"],
"RegionalNumbers" => [0,"*w"],
"Evolutions" => [0,"*ses",nil,PBEvolution],
"Abilities" => [2,"EG",PBAbilities,PBAbilities],
"Habitat" => [7,"e",["","Grassland","Forest","WatersEdge","Sea","Cave",
"Mountain","RoughTerrain","Urban","Rare"]],
"Type2" => [9,"e",PBTypes],
"Type3" => [56,"e",PBTypes],
"HiddenAbility" => [40,"EGGG",PBAbilities,PBAbilities,PBAbilities,PBAbilities],
"WildItemCommon" => [48,"E",PBItems],
"WildItemUncommon" => [50,"E",PBItems],
"WildItemRare" => [52,"E",PBItems],
"Incense" => [54,"E",PBItems]
}
currentmap = -1
dexdatas = []
eggmoves = []
entries = []
kinds = []
speciesnames = []
moves = []
evolutions = []
regionals = []
formnames = []
metrics = [SignedWordArray.new,SignedWordArray.new,SignedWordArray.new]
constants = ""
maxValue = 0
File.open("PBS/pokemon.txt","rb"){|f|
FileLineData.file = "PBS/pokemon.txt"
pbEachFileSection(f){|lastsection,currentmap|
sectionDisplay = currentmap.to_s
dexdata = []
for i in 0...76
dexdata[i] = 0
end
thesemoves = []
theseevos = []
if !lastsection["Type2"] || lastsection["Type2"]==""
if !lastsection["Type1"] || lastsection["Type1"]==""
raise _INTL("No Pokémon type is defined in section {1} (PBS/pokemon.txt)",sectionDisplay)
next
end
lastsection["Type2"] = lastsection["Type1"].clone
end
[requiredtypes,optionaltypes].each{|hash|
for key in hash.keys
FileLineData.setSection(currentmap,key,lastsection[key])
maxValue = [maxValue,currentmap].max
next if hash[key][0]<0
if currentmap==0
raise _INTL("A Pokémon species can't be numbered 0 (PBS/pokemon.txt)")
end
if !lastsection[key] || lastsection[key]==""
raise _INTL("Required entry {1} is missing or empty in section {2} (PBS/pokemon.txt)",key,sectionDisplay) if hash==requiredtypes
next
end
secvalue = lastsection[key]
rtschema = hash[key]
schema = hash[key][1]
valueindex = 0
loop do
offset = 0
minus1 = (schema[0,1]=="*") ? -1 : 0
for i in 0...schema.length
next if schema[i,1]=="*"
if (schema[i,1]=="g" || schema[i,1]=="G") && secvalue==""
dexdata[rtschema[0]+offset] = dexdata[rtschema[0]] if key=="Compatibility"
break
end
case schema[i,1]
when "e", "g"
value = csvEnumField!(secvalue,rtschema[2+i+minus1],key,sectionDisplay)
bytes = 1
when "E", "G"
value = csvEnumField!(secvalue,rtschema[2+i+minus1],key,sectionDisplay)
bytes = 2
when "i"
value = csvInt!(secvalue,key)
bytes = 1
when "u"
value = csvPosInt!(secvalue,key)
bytes = 1
when "w"
value = csvPosInt!(secvalue,key)
bytes = 2
when "f"
value = csvFloat!(secvalue,key,sectionDisplay)
value = (value*10).round
if value<=0
raise _INTL("Value '{1}' can't be less than or close to 0 (section {2}, PBS/pokemon.txt)",key,currentmap)
end
bytes = 2
when "c", "s"
value = csvfield!(secvalue)
when "S"
value = secvalue
secvalue = ""
end
case key
when "Name"
raise _INTL("Species name {1} is greater than 20 characters long (section {2}, PBS/pokemon.txt)",value,currentmap) if value.length>20
speciesnames[currentmap] = value
when "InternalName"
raise _INTL("Invalid internal name: {1} (section {2}, PBS/pokemon.txt)",value,currentmap) if !value[/^(?![0-9])\w*$/]
constants += "#{value}=#{currentmap}\r\n"
when "FormName"
formnames[currentmap] = value
when "Kind"
raise _INTL("Kind {1} is greater than 20 characters long (section {2}, PBS/pokemon.txt)",value,currentmap) if value.length>20
kinds[currentmap] = value
when "Pokedex"
entries[currentmap] = value
when "RegionalNumbers"
regionals[valueindex] = [] if !regionals[valueindex]
regionals[valueindex][currentmap]=value
when "Moves"
thesemoves.push(value)
when "EggMoves"
eggmoves[currentmap] = [] if !eggmoves[currentmap]
eggmoves[currentmap].push(value)
when "Evolutions"
theseevos.push(value)
when "BattlerPlayerY"
pbCheckSignedWord(value,key)
metrics[0][currentmap] = value
when "BattlerEnemyY"
pbCheckSignedWord(value,key)
metrics[1][currentmap] = value
when "BattlerAltitude"
pbCheckSignedWord(value,key)
metrics[2][currentmap] = value
else
dexdata[rtschema[0]+offset] = value&0xFF
dexdata[rtschema[0]+1+offset] = (value>>8)&0xFF if bytes>1
offset += bytes
end
valueindex += 1
end
break if secvalue==""
break if schema[0,1]!="*"
end
end
}
movelist = []
evolist = []
for i in 0...thesemoves.length/2
movelist.push([thesemoves[i*2],thesemoves[i*2+1],i])
end
movelist.sort!{|a,b| (a[0]==b[0]) ? a[2]<=>b[2] : a[0]<=>b[0]}
for i in movelist; i.pop; end
for i in 0...theseevos.length/3
evolist.push([theseevos[i*3],theseevos[i*3+1],theseevos[i*3+2]])
end
moves[currentmap] = movelist
evolutions[currentmap] = evolist
dexdatas[currentmap] = dexdata
}
}
if dexdatas.length==0
raise _INTL("No Pokémon species are defined in pokemon.txt")
end
count = dexdatas.compact.length
code = "module PBSpecies\r\n#{constants}"
for i in 0...speciesnames.length
speciesnames[i] = "????????" if !speciesnames[i]
end
code += "def PBSpecies.getName(id)\r\nreturn pbGetMessage(MessageTypes::Species,id)\r\nend\r\n"
code += "def PBSpecies.getCount\r\nreturn #{count}\r\nend\r\n"
code += "def PBSpecies.maxValue\r\nreturn #{maxValue}\r\nend\r\nend"
eval(code)
pbAddScript(code,"PBSpecies")
File.open("Data/dexdata.dat","wb"){|f|
mx = [maxValue,dexdatas.length-1].max
for i in 1..mx
if dexdatas[i]
dexdatas[i].each {|item| f.fputb(item)}
else
76.times { f.fputb(0) }
end
end
}
File.open("Data/attacksRS.dat","wb"){|f|
mx = [maxValue,moves.length-1].max
offset = mx*8
for i in 1..mx
f.fputdw(offset)
f.fputdw((moves[i]) ? moves[i].length*2 : 0)
offset += (moves[i]) ? moves[i].length*4 : 0
end
for i in 1..mx
next if !moves[i]
for j in moves[i]
f.fputw(j[0])
f.fputw(j[1])
end
end
}
File.open("Data/eggEmerald.dat","wb"){|f|
mx = [maxValue,eggmoves.length-1].max
offset = mx*8
for i in 1..mx
f.fputdw(offset)
f.fputdw((eggmoves[i]) ? eggmoves[i].length : 0)
offset += (eggmoves[i]) ? eggmoves[i].length*2 : 0
end
for i in 1..mx
next if !eggmoves[i]
for j in eggmoves[i]
f.fputw(j)
end
end
}
for e in 0...evolutions.length
evolist = evolutions[e]
next if !evolist
for i in 0...evolist.length
FileLineData.setSection(i,"Evolutions","")
evonib = evolist[i][1]
evolist[i][0] = csvEnumField!(evolist[i][0],PBSpecies,"Evolutions",i)
case PBEvolution::EVOPARAM[evonib]
when 1; evolist[i][2] = csvPosInt!(evolist[i][2])
when 2; evolist[i][2] = csvEnumField!(evolist[i][2],PBItems,"Evolutions",i)
when 3; evolist[i][2] = csvEnumField!(evolist[i][2],PBMoves,"Evolutions",i)
when 4; evolist[i][2] = csvEnumField!(evolist[i][2],PBSpecies,"Evolutions",i)
when 5; evolist[i][2] = csvEnumField!(evolist[i][2],PBTypes,"Evolutions",i)
else; evolist[i][2] = 0
end
evolist[i][3] = 0
end
end
_EVODATAMASK = 0x80
_EVONEXTFORM = 0x00
_EVOPREVFORM = 0x80
for e in 0...evolutions.length
evolist = evolutions[e]
next if !evolist
parent = nil
child = -1
for f in 0...evolutions.length
evolist = evolutions[f]
next if !evolist || e==f
for g in evolist
if g[0]==e && (g[3]&_EVODATAMASK)==_EVONEXTFORM
parent = g
child = f
break
end
end
break if parent
end
if parent
evolutions[e] = [[child,parent[1],parent[2],_EVOPREVFORM]].concat(evolutions[e])
end
end
File.open("Data/evolutions.dat","wb"){|f|
mx = [maxValue,evolutions.length-1].max
offset = mx*8
for i in 1..mx
f.fputdw(offset)
f.fputdw((evolutions[i]) ? evolutions[i].length*5 : 0)
offset += (evolutions[i]) ? evolutions[i].length*5 : 0
end
for i in 1..mx
next if !evolutions[i]
for j in evolutions[i]
f.fputb(j[3]|j[1])
f.fputw(j[2])
f.fputw(j[0])
end
end
}
File.open("Data/regionals.dat","wb"){|f|
f.fputw(regionals.length)
f.fputw(dexdatas.length)
for i in 0...regionals.length
for j in 0...dexdatas.length
num = regionals[i][j]
num = 0 if !num
f.fputw(num)
end
end
}
metrics[0].fillNils(dexdatas.length,0) # player Y
metrics[1].fillNils(dexdatas.length,0) # enemy Y
metrics[2].fillNils(dexdatas.length,0) # altitude
save_data(metrics,"Data/metrics.dat")
MessageTypes.setMessages(MessageTypes::Species,speciesnames)
MessageTypes.setMessages(MessageTypes::Kinds,kinds)
MessageTypes.setMessages(MessageTypes::Entries,entries)
MessageTypes.setMessages(MessageTypes::FormNames,formnames)
end
class PokeBattle_Pokemon
################################################################################
# Types
################################################################################
# Returns whether this Pokémon has the specified type.
def hasType?(type)
if type.is_a?(String) || type.is_a?(Symbol)
return isConst?(self.type1,PBTypes,type) || isConst?(self.type2,PBTypes,type) || isConst?(self.type3,PBTypes,type)
else
return self.type1==type || self.type2==type || self.type3==type
end
end
# Returns this Pokémon's first type.
def type1
dexdata=pbOpenDexData
pbDexDataOffset(dexdata,self.fSpecies,8)
ret=dexdata.fgetb
dexdata.close
return ret
end
# Returns this Pokémon's second type.
def type2
dexdata=pbOpenDexData
pbDexDataOffset(dexdata,self.fSpecies,9)
ret=dexdata.fgetb
dexdata.close
return ret
end
# Returns this Pokémon's third type.
def type3
dexdata=pbOpenDexData
pbDexDataOffset(dexdata,self.fSpecies,56)
ret=dexdata.fgetb
dexdata.close
return ret
end
end