Migrate a reorganizes bunch of files from PIF

This commit is contained in:
chardub
2025-04-24 19:46:52 -04:00
parent 682323e255
commit 95ef337de8
90 changed files with 31218 additions and 28195 deletions

Binary file not shown.

View File

@@ -203,41 +203,41 @@ module Settings
# * :areas - A hash of map IDs that determine where this Pokémon roams. Used
# instead of ROAMING_AREAS above. Optional.
ROAMING_SPECIES = [
{
:species => :LATIAS,
:level => 30,
:icon => "pin_latias",
:game_switch => 53,
:encounter_type => :all,
:bgm => "Battle roaming"
},
{
:species => :LATIOS,
:level => 30,
:icon => "pin_latios",
:game_switch => 53,
:encounter_type => :all,
:bgm => "Battle roaming"
},
{
:species => :KYOGRE,
:level => 40,
:game_switch => 54,
:encounter_type => :surfing,
:areas => {
2 => [ 21, 31 ],
21 => [2, 31, 69],
31 => [2, 21, 69],
69 => [ 21, 31 ]
}
},
{
:species => :ENTEI,
:level => 40,
:icon => "pin_entei",
:game_switch => 55,
:encounter_type => :land
}
# {
# :species => :LATIAS,
# :level => 30,
# :icon => "pin_latias",
# :game_switch => 53,
# :encounter_type => :all,
# :bgm => "Battle roaming"
# },
# {
# :species => :LATIOS,
# :level => 30,
# :icon => "pin_latios",
# :game_switch => 53,
# :encounter_type => :all,
# :bgm => "Battle roaming"
# },
# {
# :species => :KYOGRE,
# :level => 40,
# :game_switch => 54,
# :encounter_type => :surfing,
# :areas => {
# 2 => [ 21, 31 ],
# 21 => [2, 31, 69],
# 31 => [2, 21, 69],
# 69 => [ 21, 31 ]
# }
# },
# {
# :species => :ENTEI,
# :level => 40,
# :icon => "pin_entei",
# :game_switch => 55,
# :encounter_type => :land
# }
]
#-----------------------------------------------------------------------------

View File

@@ -0,0 +1,794 @@
#===============================================================================
# Abstraction layer for Pokemon Essentials
#===============================================================================
class PokemonMartAdapter
def getMoney
return $Trainer.money
end
def getMoneyString
return pbGetGoldString
end
def setMoney(value)
$Trainer.money = value
end
def getInventory
return $PokemonBag
end
def getName(item)
return GameData::Item.get(item).name
end
def getDisplayName(item)
item_name = getName(item)
if GameData::Item.get(item).is_machine?
machine = GameData::Item.get(item).move
item_name = _INTL("{1} {2}", item_name, GameData::Move.get(machine).name)
end
return item_name
end
def getDescription(item)
return GameData::Item.get(item).description
end
def getItemIcon(item)
return (item) ? GameData::Item.icon_filename(item) : nil
end
# Unused
def getItemIconRect(_item)
return Rect.new(0, 0, 48, 48)
end
def getQuantity(item)
return $PokemonBag.pbQuantity(item)
end
def showQuantity?(item)
return !GameData::Item.get(item).is_important?
end
def getPrice(item, selling = false)
if $game_temp.mart_prices && $game_temp.mart_prices[item]
if selling
return $game_temp.mart_prices[item][1] if $game_temp.mart_prices[item][1] >= 0
else
return $game_temp.mart_prices[item][0] if $game_temp.mart_prices[item][0] > 0
end
end
return GameData::Item.get(item).price
end
def getDisplayPrice(item, selling = false)
price = getPrice(item, selling).to_s_formatted
return _INTL("$ {1}", price)
end
def canSell?(item)
return getPrice(item, true) > 0 && !GameData::Item.get(item).is_important?
end
def addItem(item)
return $PokemonBag.pbStoreItem(item)
end
def removeItem(item)
return $PokemonBag.pbDeleteItem(item)
end
def getBaseColorOverride(item)
return nil
end
def getShadowColorOverride(item)
return nil
end
#specialType is a symbol
def getSpecialItemCaption(specialType)
return nil
end
def getSpecialItemDescription(specialType)
return nil
end
def doSpecialItemAction(specialType,itemId=nil)
return nil
end
def getSpecialItemBaseColor(specialType)
return nil
end
def getSpecialItemShadowColor(specialType)
return nil
end
end
#===============================================================================
# Buy and Sell adapters
#===============================================================================
class BuyAdapter
def initialize(adapter)
@adapter = adapter
end
def getDisplayName(item)
@adapter.getDisplayName(item)
end
def getDisplayPrice(item)
@adapter.getDisplayPrice(item, false)
end
def getBaseColorOverride(item)
return @adapter.getBaseColorOverride(item)
end
def getShadowColorOverride(item)
return @adapter.getShadowColorOverride(item)
end
def isSelling?
return false
end
def getSpecialItemCaption(specialType)
return @adapter.getSpecialItemCaption(specialType)
end
def getSpecialItemBaseColor(specialType)
return @adapter.getSpecialItemBaseColor(specialType)
end
def getSpecialItemShadowColor(specialType)
return @adapter.getSpecialItemShadowColor(specialType)
end
def getAdapter()
return @adapter
end
end
#===============================================================================
#
#===============================================================================
class SellAdapter
def initialize(adapter)
@adapter = adapter
end
def getDisplayName(item)
@adapter.getDisplayName(item)
end
def getDisplayPrice(item)
if @adapter.showQuantity?(item)
return sprintf("x%d", @adapter.getQuantity(item))
else
return ""
end
end
def isSelling?
return true
end
def getBaseColorOverride(item)
return @adapter.getBaseColorOverride(item)
end
def getShadowColorOverride(item)
return @adapter.getShadowColorOverride(item)
end
end
#===============================================================================
# Pokémon Mart
#===============================================================================
class Window_PokemonMart < Window_DrawableCommand
def initialize(stock, adapter, x, y, width, height, viewport = nil)
@stock = stock
@adapter = adapter
super(x, y, width, height, viewport)
@selarrow = AnimatedBitmap.new("Graphics/Pictures/martSel")
@baseColor = Color.new(88, 88, 80)
@shadowColor = Color.new(168, 184, 184)
self.windowskin = nil
end
def itemCount
return @stock.length + 1
end
def item
return (self.index >= @stock.length) ? nil : @stock[self.index]
end
def drawItem(index, count, rect)
textpos = []
rect = drawCursor(index, rect)
ypos = rect.y
if index == count - 1
textpos.push([_INTL("CANCEL"), rect.x, ypos - 4, false, self.baseColor, self.shadowColor])
else
item = @stock[index]
if item.is_a?(Symbol) && @adapter.getAdapter().is_a?(OutfitsMartAdapter)
itemname = @adapter.getSpecialItemCaption(item)
baseColor = @adapter.getSpecialItemBaseColor(item) ? @adapter.getSpecialItemBaseColor(item) : baseColor
shadowColor = @adapter.getSpecialItemShadowColor(item) ? @adapter.getSpecialItemShadowColor(item) : shadowColor
textpos.push([itemname, rect.x, ypos - 4, false, baseColor, shadowColor])
else
itemname = @adapter.getDisplayName(item)
baseColorOverride = @adapter.getBaseColorOverride(item)
shadowColorOverride = @adapter.getShadowColorOverride(item)
baseColor = baseColorOverride ? baseColorOverride : self.baseColor
shadowColor = shadowColorOverride ? shadowColorOverride : self.shadowColor
qty = @adapter.getDisplayPrice(item)
sizeQty = self.contents.text_size(qty).width
xQty = rect.x + rect.width - sizeQty - 2 - 16
textpos.push([itemname, rect.x, ypos - 4, false, baseColor, shadowColor])
textpos.push([qty, xQty, ypos - 4, false, baseColor, shadowColor])
end
end
pbDrawTextPositions(self.contents, textpos)
end
end
#===============================================================================
#
#===============================================================================
class PokemonMart_Scene
def initialize(currency_name = "Money")
@currency_name = currency_name
end
def update
pbUpdateSpriteHash(@sprites)
@subscene.pbUpdate if @subscene
end
def pbRefresh
if @subscene
@subscene.pbRefresh
else
itemwindow = @sprites["itemwindow"]
@sprites["icon"].item = itemwindow.item
@sprites["itemtextwindow"].text =
(itemwindow.item) ? @adapter.getDescription(itemwindow.item) : _INTL("Quit shopping.")
itemwindow.refresh
end
@sprites["moneywindow"].text = _INTL("{2}:\r\n<r>{1}", @adapter.getMoneyString, @currency_name)
end
def scroll_map()
pbScrollMap(6, 5, 5)
end
def scroll_back_map()
pbScrollMap(4, 5, 5)
end
def pbStartBuyOrSellScene(buying, stock, adapter)
# Scroll right before showing screen
scroll_map()
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 99999
@stock = stock
@adapter = adapter
@sprites = {}
@sprites["background"] = IconSprite.new(0, 0, @viewport)
@sprites["background"].setBitmap("Graphics/Pictures/martScreen")
@sprites["icon"] = ItemIconSprite.new(36, Graphics.height - 50, nil, @viewport)
winAdapter = buying ? BuyAdapter.new(adapter) : SellAdapter.new(adapter)
@sprites["itemwindow"] = Window_PokemonMart.new(stock, winAdapter,
Graphics.width - 316 - 16, 12, 330 + 16, Graphics.height - 126)
@sprites["itemwindow"].viewport = @viewport
@sprites["itemwindow"].index = 0
@sprites["itemwindow"].refresh
@sprites["itemtextwindow"] = Window_UnformattedTextPokemon.newWithSize("",
64, Graphics.height - 96 - 16, Graphics.width - 64, 128, @viewport)
pbPrepareWindow(@sprites["itemtextwindow"])
@sprites["itemtextwindow"].baseColor = Color.new(248, 248, 248)
@sprites["itemtextwindow"].shadowColor = Color.new(0, 0, 0)
@sprites["itemtextwindow"].windowskin = nil
@sprites["helpwindow"] = Window_AdvancedTextPokemon.new("")
pbPrepareWindow(@sprites["helpwindow"])
@sprites["helpwindow"].visible = false
@sprites["helpwindow"].viewport = @viewport
pbBottomLeftLines(@sprites["helpwindow"], 1)
@sprites["moneywindow"] = Window_AdvancedTextPokemon.new("")
pbPrepareWindow(@sprites["moneywindow"])
@sprites["moneywindow"].setSkin("Graphics/Windowskins/goldskin")
@sprites["moneywindow"].visible = true
@sprites["moneywindow"].viewport = @viewport
@sprites["moneywindow"].x = 0
@sprites["moneywindow"].y = 0
@sprites["moneywindow"].width = 190
@sprites["moneywindow"].height = 96
@sprites["moneywindow"].baseColor = Color.new(88, 88, 80)
@sprites["moneywindow"].shadowColor = Color.new(168, 184, 184)
pbDeactivateWindows(@sprites)
@buying = buying
pbRefresh
Graphics.frame_reset
end
def pbStartBuyScene(stock, adapter)
pbStartBuyOrSellScene(true, stock, adapter)
end
def pbStartSellScene(bag, adapter)
if $PokemonBag
pbStartSellScene2(bag, adapter)
else
pbStartBuyOrSellScene(false, bag, adapter)
end
end
def pbStartSellScene2(bag, adapter)
@subscene = PokemonBag_Scene.new
@adapter = adapter
@viewport2 = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport2.z = 99999
numFrames = Graphics.frame_rate * 4 / 10
alphaDiff = (255.0 / numFrames).ceil
for j in 0..numFrames
col = Color.new(0, 0, 0, j * alphaDiff)
@viewport2.color = col
Graphics.update
Input.update
end
@subscene.pbStartScene(bag)
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 99999
@sprites = {}
@sprites["helpwindow"] = Window_AdvancedTextPokemon.new("")
pbPrepareWindow(@sprites["helpwindow"])
@sprites["helpwindow"].visible = false
@sprites["helpwindow"].viewport = @viewport
pbBottomLeftLines(@sprites["helpwindow"], 1)
@sprites["moneywindow"] = Window_AdvancedTextPokemon.new("")
pbPrepareWindow(@sprites["moneywindow"])
@sprites["moneywindow"].setSkin("Graphics/Windowskins/goldskin")
@sprites["moneywindow"].visible = false
@sprites["moneywindow"].viewport = @viewport
@sprites["moneywindow"].x = 0
@sprites["moneywindow"].y = 0
@sprites["moneywindow"].width = 186
@sprites["moneywindow"].height = 96
@sprites["moneywindow"].baseColor = Color.new(88, 88, 80)
@sprites["moneywindow"].shadowColor = Color.new(168, 184, 184)
pbDeactivateWindows(@sprites)
@buying = false
pbRefresh
end
def pbEndBuyScene
pbDisposeSpriteHash(@sprites)
Kernel.pbClearText()
@viewport.dispose
# Scroll left after showing screen
scroll_back_map()
end
def pbEndSellScene
@subscene.pbEndScene if @subscene
pbDisposeSpriteHash(@sprites)
if @viewport2
numFrames = Graphics.frame_rate * 4 / 10
alphaDiff = (255.0 / numFrames).ceil
for j in 0..numFrames
col = Color.new(0, 0, 0, (numFrames - j) * alphaDiff)
@viewport2.color = col
Graphics.update
Input.update
end
@viewport2.dispose
end
@viewport.dispose
pbScrollMap(4, 5, 5) if !@subscene
end
def pbPrepareWindow(window)
window.visible = true
window.letterbyletter = false
end
def pbShowMoney
pbRefresh
@sprites["moneywindow"].visible = true
end
def pbHideMoney
pbRefresh
@sprites["moneywindow"].visible = false
end
def pbDisplay(msg, brief = false)
cw = @sprites["helpwindow"]
cw.letterbyletter = true
cw.text = msg
pbBottomLeftLines(cw, 2)
cw.visible = true
i = 0
pbPlayDecisionSE
loop do
Graphics.update
Input.update
self.update
if !cw.busy?
return if brief
pbRefresh if i == 0
end
if Input.trigger?(Input::USE) && cw.busy?
cw.resume
end
return if i >= Graphics.frame_rate * 3 / 2
i += 1 if !cw.busy?
end
end
def pbDisplayPaused(msg)
cw = @sprites["helpwindow"]
cw.letterbyletter = true
cw.text = msg
pbBottomLeftLines(cw, 2)
cw.visible = true
yielded = false
pbPlayDecisionSE
loop do
Graphics.update
Input.update
wasbusy = cw.busy?
self.update
if !cw.busy? && !yielded
yield if block_given? # For playing SE as soon as the message is all shown
yielded = true
end
pbRefresh if !cw.busy? && wasbusy
if Input.trigger?(Input::USE) && cw.resume && !cw.busy?
@sprites["helpwindow"].visible = false
return
end
end
end
def pbConfirm(msg)
dw = @sprites["helpwindow"]
dw.letterbyletter = true
dw.text = msg
dw.visible = true
pbBottomLeftLines(dw, 2)
commands = [_INTL("Yes"), _INTL("No")]
cw = Window_CommandPokemon.new(commands)
cw.viewport = @viewport
pbBottomRight(cw)
cw.y -= dw.height
cw.index = 0
pbPlayDecisionSE
loop do
cw.visible = !dw.busy?
Graphics.update
Input.update
cw.update
self.update
if Input.trigger?(Input::BACK) && dw.resume && !dw.busy?
cw.dispose
@sprites["helpwindow"].visible = false
return false
end
if Input.trigger?(Input::USE) && dw.resume && !dw.busy?
cw.dispose
@sprites["helpwindow"].visible = false
return (cw.index == 0)
end
end
end
def pbChooseNumber(helptext, item, maximum)
curnumber = 1
ret = 0
helpwindow = @sprites["helpwindow"]
itemprice = @adapter.getPrice(item, !@buying)
itemprice /= 2 if !@buying
pbDisplay(helptext, true)
using(numwindow = Window_AdvancedTextPokemon.new("")) { # Showing number of items
qty = @adapter.getQuantity(item)
using(inbagwindow = Window_AdvancedTextPokemon.new("")) { # Showing quantity in bag
pbPrepareWindow(numwindow)
pbPrepareWindow(inbagwindow)
numwindow.viewport = @viewport
numwindow.width = 224
numwindow.height = 64
numwindow.baseColor = Color.new(88, 88, 80)
numwindow.shadowColor = Color.new(168, 184, 184)
inbagwindow.visible = @buying
inbagwindow.viewport = @viewport
inbagwindow.width = 190
inbagwindow.height = 64
inbagwindow.baseColor = Color.new(88, 88, 80)
inbagwindow.shadowColor = Color.new(168, 184, 184)
inbagwindow.text = _INTL("In Bag:<r>{1} ", qty)
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
pbBottomRight(numwindow)
numwindow.y -= helpwindow.height
pbBottomLeft(inbagwindow)
inbagwindow.y -= helpwindow.height
loop do
Graphics.update
Input.update
numwindow.update
inbagwindow.update
self.update
if Input.repeat?(Input::LEFT)
pbPlayCursorSE
curnumber -= 10
curnumber = 1 if curnumber < 1
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
elsif Input.repeat?(Input::RIGHT)
pbPlayCursorSE
curnumber += 10
curnumber = maximum if curnumber > maximum
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
elsif Input.repeat?(Input::UP)
pbPlayCursorSE
curnumber += 1
curnumber = 1 if curnumber > maximum
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
elsif Input.repeat?(Input::DOWN)
pbPlayCursorSE
curnumber -= 1
curnumber = maximum if curnumber < 1
numwindow.text = _INTL("x{1}<r>$ {2}", curnumber, (curnumber * itemprice).to_s_formatted)
elsif Input.trigger?(Input::USE)
pbPlayDecisionSE
ret = curnumber
break
elsif Input.trigger?(Input::BACK)
pbPlayCancelSE
ret = 0
break
end
end
}
}
helpwindow.visible = false
return ret
end
def pbChooseBuyItem
itemwindow = @sprites["itemwindow"]
@sprites["helpwindow"].visible = false
pbActivateWindow(@sprites, "itemwindow") {
pbRefresh
loop do
Graphics.update
Input.update
olditem = itemwindow.item
self.update
if itemwindow.item != olditem
@sprites["icon"].item = itemwindow.item
@sprites["itemtextwindow"].text =
(itemwindow.item) ? @adapter.getDescription(itemwindow.item) : _INTL("Quit shopping.")
end
if Input.trigger?(Input::BACK)
pbPlayCloseMenuSE
return nil
elsif Input.trigger?(Input::USE)
if itemwindow.index < @stock.length
pbRefresh
return @stock[itemwindow.index]
else
return nil
end
end
end
}
end
def pbChooseSellItem
if @subscene
return @subscene.pbChooseItem
else
return pbChooseBuyItem
end
end
end
#===============================================================================
#
#===============================================================================
class PokemonMartScreen
def initialize(scene, stock, adapter = PokemonMartAdapter.new)
@scene = scene
@stock = stock
@adapter = adapter
end
def pbConfirm(msg)
return @scene.pbConfirm(msg)
end
def pbDisplay(msg)
return @scene.pbDisplay(msg)
end
def pbDisplayPaused(msg, &block)
return @scene.pbDisplayPaused(msg, &block)
end
def pbBuyScreen
@scene.pbStartBuyScene(@stock, @adapter)
item = nil
loop do
pbWait(4)
item = @scene.pbChooseBuyItem
break if !item
quantity = 0
itemname = @adapter.getDisplayName(item)
price = @adapter.getPrice(item)
if @adapter.getMoney < price
pbDisplayPaused(_INTL("You don't have enough money."))
next
end
if GameData::Item.get(item).is_important?
if !pbConfirm(_INTL("Certainly. You want {1}. That will be ${2}. OK?",
itemname, price.to_s_formatted))
next
end
quantity = 1
else
maxafford = (price <= 0) ? Settings::BAG_MAX_PER_SLOT : @adapter.getMoney / price
maxafford = Settings::BAG_MAX_PER_SLOT if maxafford > Settings::BAG_MAX_PER_SLOT
quantity = @scene.pbChooseNumber(
_INTL("{1}? Certainly. How many would you like?", itemname), item, maxafford)
next if quantity == 0
price *= quantity
if !pbConfirm(_INTL("{1}, and you want {2}. That will be ${3}. OK?",
itemname, quantity, price.to_s_formatted))
next
end
end
if @adapter.getMoney < price
pbDisplayPaused(_INTL("You don't have enough money."))
next
end
added = 0
quantity.times do
break if !@adapter.addItem(item)
added += 1
end
if added != quantity
added.times do
if !@adapter.removeItem(item)
raise _INTL("Failed to delete stored items")
end
end
pbDisplayPaused(_INTL("You have no more room in the Bag."))
else
@adapter.setMoney(@adapter.getMoney - price)
for i in 0...@stock.length
if GameData::Item.get(@stock[i]).is_important? && $PokemonBag.pbHasItem?(@stock[i])
@stock[i] = nil
end
end
@stock.compact!
pbDisplayPaused(_INTL("Here you are! Thank you!")) { pbSEPlay("Mart buy item") }
if $PokemonBag
if quantity >= 10 && GameData::Item.get(item).is_poke_ball? && GameData::Item.exists?(:PREMIERBALL)
if @adapter.addItem(GameData::Item.get(:PREMIERBALL))
pbDisplayPaused(_INTL("I'll throw in a Premier Ball, too."))
end
end
end
end
end
@scene.pbEndBuyScene
end
def pbSellScreen
item = @scene.pbStartSellScene(@adapter.getInventory, @adapter)
loop do
item = @scene.pbChooseSellItem
break if !item
itemname = @adapter.getDisplayName(item)
price = @adapter.getPrice(item, true)
if !@adapter.canSell?(item)
pbDisplayPaused(_INTL("{1}? Oh, no. I can't buy that.", itemname))
next
end
qty = @adapter.getQuantity(item)
next if qty == 0
@scene.pbShowMoney
if qty > 1
qty = @scene.pbChooseNumber(
_INTL("{1}? How many would you like to sell?", itemname), item, qty)
end
if qty == 0
@scene.pbHideMoney
next
end
price /= 2
price *= qty
if pbConfirm(_INTL("I can pay ${1}. Would that be OK?", price.to_s_formatted))
@adapter.setMoney(@adapter.getMoney + price)
qty.times do
@adapter.removeItem(item)
end
pbDisplayPaused(_INTL("Turned over the {1} and received ${2}.", itemname, price.to_s_formatted)) { pbSEPlay("Mart buy item") }
@scene.pbRefresh
end
@scene.pbHideMoney
end
@scene.pbEndSellScene
end
end
def replaceShopStockWithRandomized(stock)
if $PokemonGlobal.randomItemsHash != nil
newStock = []
for item in stock
newItem = $PokemonGlobal.randomItemsHash[item]
if newItem != nil && GameData::Item.get(newItem).price > 0 && !Settings::EXCLUDE_FROM_RANDOM_SHOPS.include?(newItem)
newStock << newItem
else
newStock << item
end
end
return newStock
end
return stock
end
#===============================================================================
#
#===============================================================================
def pbPokemonMart(stock, speech = nil, cantsell = false)
if $game_switches[SWITCH_RANDOM_ITEMS_GENERAL] && $game_switches[SWITCH_RANDOM_SHOP_ITEMS]
stock = replaceShopStockWithRandomized(stock)
end
for i in 0...stock.length
stock[i] = GameData::Item.get(stock[i]).id
stock[i] = nil if GameData::Item.get(stock[i]).is_important? && $PokemonBag.pbHasItem?(stock[i])
end
stock.compact!
commands = []
cmdBuy = -1
cmdSell = -1
cmdQuit = -1
commands[cmdBuy = commands.length] = _INTL("Buy")
commands[cmdSell = commands.length] = _INTL("Sell") if !cantsell
commands[cmdQuit = commands.length] = _INTL("Quit")
cmd = pbMessage(
speech ? speech : _INTL("Welcome! How may I serve you?"),
commands, cmdQuit + 1)
loop do
if cmdBuy >= 0 && cmd == cmdBuy
scene = PokemonMart_Scene.new
screen = PokemonMartScreen.new(scene, stock)
screen.pbBuyScreen
elsif cmdSell >= 0 && cmd == cmdSell
scene = PokemonMart_Scene.new
screen = PokemonMartScreen.new(scene, stock)
screen.pbSellScreen
else
pbMessage(_INTL("Please come again!"))
break
end
cmd = pbMessage(_INTL("Is there anything else I can help you with?"),
commands, cmdQuit + 1)
end
$game_temp.clear_mart_prices
end

View File

@@ -0,0 +1,4 @@
module MessageConfig
BLUE_TEXT_MAIN_COLOR = Color.new(35, 130, 200)
BLUE_TEXT_SHADOW_COLOR = Color.new(20, 75, 115)
end

View File

@@ -0,0 +1,6 @@
##############
# ANIMATIONS
################
DUST_ANIMATION_ID=2
VIRUS_ANIMATION_ID=10# frozen_string_literal: true

View File

@@ -0,0 +1,31 @@
#############
# SETTINGS #
#############
# This is for settings that are used in scripts since it's a chore to change them everywhere to include the module name
NUM_BADGES = Settings::NB_BADGES
EGGINITIALLEVEL = Settings::EGG_LEVEL
#this is fucking stupid but apparently necessary
FALSE = false
TRUE = true
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
VAR_SPEED_UP_TOGGLE_SPEED=23
MAP_TEMPLATE_EVENTS = 175
TEMPLATE_EVENT_SILHOUETTE = 7
SWITCH_TRIPLE_BOSS_BATTLE = 824
SWITCH_SILVERBOSS_BATTLE = 675
GENDER_FEMALE=0
GENDER_MALE=1
MELOETTA_BAND_NAME = "Miss Melody and the Mystic Musicians"
SUCKY_BAND_NAME = "MooMoo Milk"

View File

@@ -0,0 +1,93 @@
# frozen_string_literal: true
KANTO_OUTDOOR_MAPS = [
78, # Route 1
185, # Secret Garden
86, # Route 2
90, # Route 2 (north)
655, # Hidden Forest
40, # Viridian River
490, # Route 3
106, # Route 4
12, # Route 5
16, # Route 6
413, # Route 7
409, # Route 8
351, # Route 9 (east)
495, # Route 9 (west)
154, # Route 10
155, # Route 11
159, # Route 12
440, # Route 14
444, # Route 15
712, # Creepy house
438, # Route 16
146, # Route 17
517, # Route 18
437, # Route 13
57, # Route 19
227, # Route 19 (underwater)
56, # Route 19 (surf race)
58, # Route 20
480, # Route 20 underwater 1
228, # Route 20 underwater 2
171, # Route 22
8, # Route 24
9, # Route 25
143, # Route 23
145, # Route 26
147, # Route 27
58, # Route 21
# CITIES
42, # Pallet Town
79, # Viridian City
1, # Cerulean City
387, # Cerulean City (race)
19, # Vermillion City
36, # S.S. Anne deck
95, # Celadon city
436, # Celadon city dept store (roof)
472, # Fuchsia city
50, # Lavender town
108, # Saffron city
98, # Cinnabar island
167, # Crimson city
303, # indigo plateau
380, # Pewter city
827, # Mt. Moon summit
#
# DUNGEONS
#
102, # Mt. Moon
103, # Mt. Moon
105, # Mt. Moon
496, # Mt Moon
104, # Mt. Moon
494, # Mt. Moon Square
140, # Diglett cave
398, # Diglett cave
399, # Diglett cave
349, # Rock tunnel
350, # Rock tunnel
512, # Rock tunnel (outdoor)
445, # Safari Zone 1
484, # Safari Zone 2
485, # Safari Zone 3
486, # Safari Zone 4
487, # Safari Zone 5
491, # Viridian Forest
529, # Mt. Silver entrance
777, # Mt. Silver outdoor 1
781, # Mt. Silver outdoor 2
782, # Mt. Silver
783, # Mt. Silver summit
400, # Pokemon Tower
401, # Pokemon Tower
402, # Pokemon Tower
403, # Pokemon Tower
467, # Pokemon Tower
468, # Pokemon Tower
469, # Pokemon Tower
]

View File

@@ -0,0 +1,172 @@
# frozen_string_literal: true
#############
# SWITCHES #
#############
#Game mode switches
SWITCH_NEW_GAME_PLUS = 972
SWITCH_BEAT_MT_SILVER = 918
BEAT_MT_SILVER = 918 #don't remove this - used in some events
SWITCH_REVERSED_MODE = 47
SWITCH_GAME_DIFFICULTY_EASY = 665
SWITCH_GAME_DIFFICULTY_HARD = 666
SWITCH_MODERN_MODE=974
SWITCH_EXPERT_MODE=772
SWITCH_V5_1=825
SWITCH_NO_LEVELS_MODE=774
SWITCH_DOUBLE_ABILITIES=773
SWITCH_SINGLE_SPECIES_MODE=790
#Game progression switches
SWITCH_DURING_INTRO = 917
SWITCH_CHOOSING_STARTER=3
SWITCH_GOT_BADGE_1 = 4
SWITCH_GOT_BADGE_2 = 5
SWITCH_GOT_BADGE_3 = 6
SWITCH_GOT_BADGE_4 = 7
SWITCH_GOT_BADGE_5 = 8
SWITCH_GOT_BADGE_6 = 9
SWITCH_GOT_BADGE_7 = 10
SWITCH_GOT_BADGE_8 = 11
SWITCH_BEAT_THE_LEAGUE = 12
SWITCH_GOT_BADGE_9 = 38
SWITCH_GOT_BADGE_10 = 39
SWITCH_GOT_BADGE_11 = 40
SWITCH_GOT_BADGE_12 = 41
SWITCH_GOT_BADGE_13 = 43
SWITCH_GOT_BADGE_14 = 44
SWITCH_GOT_BADGE_15 = 45
SWITCH_GOT_BADGE_16 = 50
SWITCH_KANTO_DARKNESS = 701
SWITCH_KANTO_DARKNESS_STAGE_1 = 702
SWITCH_KANTO_DARKNESS_STAGE_2 = 703
SWITCH_KANTO_DARKNESS_STAGE_3 = 704
SWITCH_KANTO_DARKNESS_STAGE_4 = 705
SWITCH_ORICORIO_QUEST_PINK = 672
SWITCH_ORICORIO_QUEST_RED = 673
SWITCH_ORICORIO_QUEST_BLUE = 674
SWITCH_ORICORIO_QUEST_IN_PROGRESS = 680
SWITCH_PICKED_HELIC_FOSSIL= 65
SWITCH_PICKED_DOME_FOSSIL= 66
SWITCH_PICKED_LILEEP_FOSSIL= 589
SWITCH_PICKED_ANORITH_FOSSIL= 90
SWITCH_PICKED_ARMOR_FOSSIL= 616
SWITCH_PICKED_SKULL_FOSSIL= 617
SWITCH_NIGHTMARE_EFFECT= 805
SWITCH_JOHTO_STARTERS=884
SWITCH_HOENN_STARTERS=885
SWITCH_SINNOH_STARTERS=886
SWITCH_KALOS_STARTERS=888
SWITCH_CUSTOM_STARTERS=883
SWITCH_JOINED_TEAM_ROCKET=1037
SWITCH_PINKAN_SIDE_ROCKET=1099
SWITCH_PINKAN_SIDE_POLICE=1100
SWITCH_LEAVING_PINKAN_ISLAND=1113
SWITCH_BLOCK_PINKAN_WHISTLE=1111
SWITCH_PINKAN_FINISHED=1119
VAR_ORICORIO_FLOWERS = 276
#Randomizer Switches
SWITCH_RANDOM_WILD_TO_FUSION=953
SWITCH_RANDOMIZED_AT_LEAST_ONCE = 855
ENABLED_DEBUG_MODE_AT_LEAST_ONCE = 842
SWITCH_RANDOM_WILD = 778
SWITCH_RANDOM_WILD_AREA = 777
SWITCH_RANDOM_TRAINERS = 987
SWITCH_RANDOM_STARTERS = 954
SWITCH_RANDOM_STARTER_FIRST_STAGE = 771
SWITCH_RANDOM_ITEMS_GENERAL=759
SWITCH_RANDOM_ITEMS=751
SWITCH_RANDOM_FOUND_ITEMS=755
SWITCH_RANDOM_ITEMS_DYNAMIC = 958
SWITCH_RANDOM_ITEMS_MAPPED = 752
SWITCH_RANDOM_TMS = 758
SWITCH_RANDOM_GIVEN_ITEMS = 756
SWITCH_RANDOM_GIVEN_TMS = 757
SWITCH_RANDOM_SHOP_ITEMS = 754
SWITCH_RANDOM_FOUND_TMS = 959
SWITCH_WILD_RANDOM_GLOBAL=956
SWITCH_RANDOM_STATIC_ENCOUNTERS=955
SWITCH_RANDOM_WILD_ONLY_CUSTOMS=664
SWITCH_RANDOM_GYM_PERSIST_TEAMS=663
SWITCH_GYM_RANDOM_EACH_BATTLE = 668
SWITCH_RANDOM_GYM_CUSTOMS=662
SWITCH_RANDOMIZE_GYMS_SEPARATELY = 667
SWITCH_RANDOMIZED_GYM_TYPES=921
SWITCH_RANDOM_GIFT_POKEMON = 780
SWITCH_RANDOM_HELD_ITEMS = 843
SWITCH_DEFINED_RIVAL_STARTER=840
SWITCH_RANDOMIZED_WILD_POKEMON_TO_FUSIONS=829
SWITCH_RANDOM_WILD_LEGENDARIES=1031
SWITCH_RANDOM_TRAINER_LEGENDARIES=1032
SWITCH_RANDOM_GYM_LEGENDARIES=1033
SWITCH_DONT_RANDOMIZE=890
#Other switches
SWITCH_RACE_BIKE = 984
SWITCH_IS_REMATCH=200
SWITCH_SINGLE_POKEMON_MODE=790
SWITCH_SINGLE_POKEMON_MODE_HEAD=791
SWITCH_SINGLE_POKEMON_MODE_BODY=792
SWITCH_SINGLE_POKEMON_MODE_RANDOM=793
SWITCH_FISHING_AUTOHOOK = 916
SWITCH_FUSED_WILD_POKEMON=35
SWITCH_FORCE_FUSE_NEXT_POKEMON=37
SWITCH_FORCE_ALL_WILD_FUSIONS=828
SWITCH_USED_AN_INCENSE=798
SWITCH_FIRST_RIVAL_BATTLE=46
SWITCH_BATTLE_FACTORY_INCLUDE_ALL = 775
SWITCH_SUPER_SLOW_SPEED=649
SWITCH_LOUNGE_BATTLE_LEVEL = 240
SWITCH_CANNOT_CATCH_POKEMON = 75
SWITCH_UNLOCKED_POKEMON_HATS = 770
SWITCH_ILEX_FOREST_SPOOKED_POKEMON = 1021
SWITCH_LOCK_PLAYER_MOVEMENT = 815
SWITCH_TEAMED_WITH_ERIKA_SEWERS=141
SWITCH_BAND_DRUMMER = 1004
SWITCH_BAND_ACOUSTIC_GUITAR = 1005
SWITCH_BAND_ELECTRIC_GUITAR = 1006
SWITCH_BAND_HARP = 1007
SWITCH_BAND_FLUTE = 1008
SWITCH_SELECTING_CLOTHES = 804
SWITCH_KANTO_HAIR_COLLECTION = 1059
SWITCH_JOHTO_HAIR_COLLECTION = 1060
SWITCH_HOENN_HAIR_COLLECTION = 1061
SWITCH_SINNOH_HAIR_COLLECTION = 1062
SWITCH_UNOVA_HAIR_COLLECTION = 1063
SWITCH_KALOS_HAIR_COLLECTION = 1064
SWITCH_ALOLA_HAIR_COLLECTION = 1065
SWITCH_GALAR_HAIR_COLLECTION = 1066
SWITCH_PALDEA_HAIR_COLLECTION = 1067
SWITCH_GEN10_HAIR_COLLECTION = 1068
SWITCH_SS_ANNE_DEPARTED = 88
SWITCH_SNORLAX_GONE_ROUTE_12 = 110
SWITCH_TELEPORT_NPC = 122
SWITCH_GOT_DIVE = 317
SWITCH_GOT_ROCK_CLIMB = 661
SWITCH_GOT_WATERFALL = 388
SWITCH_UPDATED_TO_SPRITESHEETS_SPRITES=1117
#OUTFITS
#
WEARING_ROCKET_OUTFIT = 1038

View File

@@ -0,0 +1,131 @@
# frozen_string_literal: true
#############
# VARIABLES #
#############
VAR_CURRENT_MART=291
VAR_CURRENT_CITY_NUMERICAL_ID=14 #for wondertrade/pokemarts
VAR_SINGLE_POKEMON_MODE=251
SINGLE_POKEMON_MODE_VAR=251 #c'est appellé comme ca en qqpart dans un event pis ca me tente pas de chercher ou
VAR_WILD_FUSION_RATE=210
VAR_ODDKEYSTONE_NB=252
VAR_DEFAULT_BATTLE_TYPE = 242
VAR_BATTLE_FACTORY_TOKENS = 243
VAR_NB_GYM_REMATCHES = 162
VAR_CUSTOM_SPRITES_ENABLED= 196
VAR_COMMAND_WINDOW_INDEX=249
VAR_STANDARD_WONDERTRADE_LEFT=248
VAR_PREMIUM_WONDERTRADE_LEFT=111
VAR_PREMIUM_WONDERTRADE_LEFT=111
VAR_RIVAL_STARTER=250
VAR_FUSION_ICON_STYLE=220
VAR_SHINY_HUE_OFFSET=275
VAR_CURRENT_HIDDEN_MAP = 226
VAR_FUSE_COUNTER = 126
VAR_STAT_RARE_CANDY=265
VAR_STAT_LEADER_REMATCH=162
VAR_STAT_NB_FUSIONS=126
VAR_STAT_NB_ELITE_FOUR=174
VAR_STAT_NB_WONDERTRADES=164
VAR_STAT_CLOWN_TIP_TOTAL=100
VAR_STAT_NB_SANDCASTLES=163
VAR_STAT_GAMBLER_WINS=43
VAR_STAT_GAMBLER_LOSSES=44
VAR_STAT_HOTELS_SPENT=225
VAR_NB_EGGS_HATCHED=298
VAR_STAT_QUESTS_ACCEPTED=96
VAR_STAT_QUESTS_COMPLETED=98
VAR_NB_ROCKET_MISSIONS = 286
VAR_BOUTIQUE_OUTFIT=290
VAR_FISHING_CONTEST_RECORD=294
VAR_FISHING_CONTEST_NERF=333
VAR_STAT_NB_SECRETS=193
VAR_STAT_FUSION_QUIZ_HIGHEST_SCORE=267
VAR_STAT_FUSION_QUIZ_NB_TIMES=268
VAR_STAT_FUSION_QUIZ_TOTAL_PTS=269
VAR_KARMA=222
VAR_NB_QUEST_ACTIVE=97
VAR_NB_QUEST_COMPLETED=98
VAR_LUNAR_FEATHERS=282
VAR_FOSSIL=271
VAR_SSANNE_MENU=313
VAR_TEMP_SSANNE_ORDER=314
VAR_TEMP_SSANNE_PLATE=325
VAR_SSANNE_DISHES_HELD_ARRAY=316
VAR_BATTLE_TOWER_MIN_BST = 257
VAR_BATTLE_TOWER_MAX_BST = 258
VAR_GALLERY_FEATURED_ARTIST = 259
VAR_GALLERY_FEATURED_SPRITES = 260
VAR_GALLERY_ALL_ARTIST_SPRITES = 261
VAR_GALLERY_SELECTED_ARTIST = 263
VAR_NEXT_ARTIST_FORMATTED = 264
VAR_RADIO_POINTS=266
VAR_TRAINER_GENDER=52
VAR_TRAINER_AGE=99
VAR_ROCKET_NAME=25
VAR_NB_CRIMES_REPORTED=300
VAR_EXOTIC_POKEMON_ID=327
VAR_TYPE_EXPERTS_BEATEN=332
TOTAL_NB_TYPE_EXPERTS=331
#Randomizer
VAR_RANDOMIZER_WILD_POKE_BST=197
VAR_RANDOMIZER_TRAINER_BST=195
VAR_GYM_TYPES_ARRAY=151
VAR_CURRENT_GYM_TYPE=152
#constellations
VAR_CONSTELLATION_IVYSAUR=301
VAR_CONSTELLATION_WARTORTLE=302
VAR_CONSTELLATION_ARCANINE=303
VAR_CONSTELLATION_MACHOKE=304
VAR_CONSTELLATION_RAPIDASH=305
VAR_CONSTELLATION_GYARADOS=306
VAR_CONSTELLATION_ARTICUNO=307
VAR_CONSTELLATION_MEW=308
VAR_CONSTELLATION_POLITOED=309
VAR_CONSTELLATION_URSARING=310
VAR_CONSTELLATION_LUGIA=311
VAR_CONSTELLATION_HOOH=312
VAR_CONSTELLATION_CELEBI=313
VAR_CONSTELLATION_SLAKING=314
VAR_CONSTELLATION_JIRACHI=315
VAR_CONSTELLATION_TYRANTRUM=316
VAR_CONSTELLATION_SHARPEDO=317
VAR_CONSTELLATION_ARCEUS=318
VAR_LATEST_CONSTELLATION=319
VAR_TRAINER_CARD_BACKGROUND_PRICE=329
VAR_GALLERY_TEAM_FLAGS=330
VAR_REGI_PUZZLE_SWITCH_PRESSED = 1122
##############
# COMMON EVENTS
################
COMMON_EVENT_REGI_TABLET = 84
COMMON_EVENT_SILHOUETTE = 87
COMMON_EVENT_HOTEL = 12
COMMON_EVENT_SINGLESPECIES_MODE = 73
COMMON_EVENT_OUTFIT = 80
COMMON_EVENT_FIX_GAME = 16
COMMON_EVENT_IDLE_HAT = 100
COMMON_EVENT_PINKAN_WHISTLE = 106
COMMON_EVENT_PINKAN_BACK_TO_BEGIN = 103

View File

@@ -0,0 +1,323 @@
def getPokemonPositionInParty(pokemon)
for i in 0..$Trainer.party.length
if $Trainer.party[i] == pokemon
return i
end
end
return -1
end
# don't remember why there's two Supersplicers arguments.... probably a mistake
def pbDNASplicing(pokemon, scene, item = :DNASPLICERS)
is_supersplicer = isSuperSplicersMechanics(item)
playingBGM = $game_system.getPlayingBGM
dexNumber = pokemon.species_data.id_number
if (pokemon.species_data.id_number <= NB_POKEMON)
if pokemon.fused != nil
if $Trainer.party.length >= 6
scene.pbDisplay(_INTL("Your party is full! You can't unfuse {1}.", pokemon.name))
return false
else
$Trainer.party[$Trainer.party.length] = pokemon.fused
pokemon.fused = nil
pokemon.form = 0
scene.pbHardRefresh
scene.pbDisplay(_INTL("{1} changed Forme!", pokemon.name))
return true
end
else
chosen = scene.pbChoosePokemon(_INTL("Fuse with which Pokémon?"))
if chosen >= 0
poke2 = $Trainer.party[chosen]
if (poke2.species_data.id_number <= NB_POKEMON) && poke2 != pokemon
# check if fainted
if pokemon.egg? || poke2.egg?
scene.pbDisplay(_INTL("It's impossible to fuse an egg!"))
return false
end
if pokemon.hp == 0 || poke2.hp == 0
scene.pbDisplay(_INTL("A fainted Pokémon cannot be fused!"))
return false
end
selectedHead = selectFusion(pokemon, poke2, is_supersplicer)
if selectedHead == -1 # cancelled
return false
end
if selectedHead == nil # can't fuse (egg, etc.)
scene.pbDisplay(_INTL("It won't have any effect."))
return false
end
selectedBase = selectedHead == pokemon ? poke2 : pokemon
firstOptionSelected = selectedHead == pokemon
if !firstOptionSelected
chosen = getPokemonPositionInParty(pokemon)
if chosen == -1
scene.pbDisplay(_INTL("There was an error..."))
return false
end
end
if (Kernel.pbConfirmMessage(_INTL("Fuse {1} and {2}?", selectedHead.name, selectedBase.name)))
pbFuse(selectedHead, selectedBase, item)
pbRemovePokemonAt(chosen)
scene.pbHardRefresh
pbBGMPlay(playingBGM)
return true
end
elsif pokemon == poke2
scene.pbDisplay(_INTL("{1} can't be fused with itself!", pokemon.name))
return false
else
scene.pbDisplay(_INTL("{1} can't be fused with {2}.", poke2.name, pokemon.name))
return false
end
else
return false
end
end
else
# UNFUSE
return true if pbUnfuse(pokemon, scene, is_supersplicer)
end
end
def selectFusion(pokemon, poke2, supersplicers = false)
return nil if !pokemon.is_a?(Pokemon) || !poke2.is_a?(Pokemon)
return nil if pokemon.egg? || poke2.egg?
selectorWindow = FusionPreviewScreen.new(poke2, pokemon, supersplicers) # PictureWindow.new(picturePath)
selectedHead = selectorWindow.getSelection
selectorWindow.dispose
return selectedHead
end
# firstOptionSelected= selectedHead == pokemon
# selectedBody = selectedHead == pokemon ? poke2 : pokemon
# newid = (selectedBody.species_data.id_number) * NB_POKEMON + selectedHead.species_data.id_number
# def pbFuse(pokemon, poke2, supersplicers = false)
# newid = (pokemon.species_data.id_number) * NB_POKEMON + poke2.species_data.id_number
# previewwindow = FusionPreviewScreen.new(pokemon, poke2)#PictureWindow.new(picturePath)
#
# if (Kernel.pbConfirmMessage(_INTL("Fuse the two Pokémon?", newid)))
# previewwindow.dispose
# fus = PokemonFusionScene.new
# if (fus.pbStartScreen(pokemon, poke2, newid))
# returnItemsToBag(pokemon, poke2)
# fus.pbFusionScreen(false, supersplicers)
# $game_variables[126] += 1 #fuse counter
# fus.pbEndScreen
# return true
# end
# else
# previewwindow.dispose
# return false
# end
# end
def pbFuse(pokemon_body, pokemon_head, splicer_item)
use_supersplicers_mechanics = isSuperSplicersMechanics(splicer_item)
newid = (pokemon_body.species_data.id_number) * NB_POKEMON + pokemon_head.species_data.id_number
fus = PokemonFusionScene.new
if (fus.pbStartScreen(pokemon_body, pokemon_head, newid, splicer_item))
returnItemsToBag(pokemon_body, pokemon_head)
fus.pbFusionScreen(false, use_supersplicers_mechanics)
$game_variables[VAR_FUSE_COUNTER] += 1 # fuse counter
fus.pbEndScreen
return true
end
end
# Todo: refactor this, holy shit this is a mess
def pbUnfuse(pokemon, scene, supersplicers, pcPosition = nil)
if pokemon.species_data.id_number > (NB_POKEMON * NB_POKEMON) + NB_POKEMON # triple fusion
scene.pbDisplay(_INTL("{1} cannot be unfused.", pokemon.name))
return false
end
if pokemon.owner.name == "RENTAL"
scene.pbDisplay(_INTL("You cannot unfuse a rental pokémon!"))
return
end
pokemon.spriteform_body = nil
pokemon.spriteform_head = nil
bodyPoke = getBasePokemonID(pokemon.species_data.id_number, true)
headPoke = getBasePokemonID(pokemon.species_data.id_number, false)
if (pokemon.foreign?($Trainer)) # && !canunfuse
scene.pbDisplay(_INTL("You can't unfuse a Pokémon obtained in a trade!"))
return false
else
if Kernel.pbConfirmMessageSerious(_INTL("Should {1} be unfused?", pokemon.name))
keepInParty = 0
if $Trainer.party.length >= 6 && !pcPosition
message = "Your party is full! Keep which Pokémon in party?"
message = "Your party is full! Keep which Pokémon in party? The other will be released." if isOnPinkanIsland()
scene.pbDisplay(_INTL(message))
selectPokemonMessage = "Select a Pokémon to keep in your party."
selectPokemonMessage = "Select a Pokémon to keep in your party. The other will be released" if isOnPinkanIsland()
choice = Kernel.pbMessage(selectPokemonMessage, [_INTL("{1}", PBSpecies.getName(bodyPoke)), _INTL("{1}", PBSpecies.getName(headPoke)), "Cancel"], 2)
if choice == 2
return false
else
keepInParty = choice
end
end
scene.pbDisplay(_INTL("Unfusing ... "))
scene.pbDisplay(_INTL(" ... "))
scene.pbDisplay(_INTL(" ... "))
if pokemon.exp_when_fused_head == nil || pokemon.exp_when_fused_body == nil
new_level = calculateUnfuseLevelOldMethod(pokemon, supersplicers)
body_level = new_level
head_level = new_level
poke1 = Pokemon.new(bodyPoke, body_level)
poke2 = Pokemon.new(headPoke, head_level)
else
exp_body = pokemon.exp_when_fused_body + pokemon.exp_gained_since_fused
exp_head = pokemon.exp_when_fused_head + pokemon.exp_gained_since_fused
poke1 = Pokemon.new(bodyPoke, pokemon.level)
poke2 = Pokemon.new(headPoke, pokemon.level)
poke1.exp = exp_body
poke2.exp = exp_head
end
body_level = poke1.level
head_level = poke2.level
pokemon.exp_gained_since_fused = 0
pokemon.exp_when_fused_head = nil
pokemon.exp_when_fused_body = nil
if pokemon.shiny?
pokemon.shiny = false
if pokemon.bodyShiny? && pokemon.headShiny?
pokemon.shiny = true
poke2.shiny = true
pokemon.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
poke2.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
elsif pokemon.bodyShiny?
pokemon.shiny = true
poke2.shiny = false
pokemon.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
elsif pokemon.headShiny?
poke2.shiny = true
pokemon.shiny = false
poke2.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
else
# shiny was obtained already fused
if rand(2) == 0
pokemon.shiny = true
else
poke2.shiny = true
end
end
end
fused_pokemon_learned_moved = pokemon.learned_moves
pokemon.learned_moves = fused_pokemon_learned_moved
poke2.learned_moves = fused_pokemon_learned_moved
pokemon.ability_index = pokemon.body_original_ability_index if pokemon.body_original_ability_index
poke2.ability_index = pokemon.head_original_ability_index if pokemon.head_original_ability_index
pokemon.ability2_index = nil
pokemon.ability2 = nil
poke2.ability2_index = nil
poke2.ability2 = nil
pokemon.debug_shiny = true if pokemon.debug_shiny && pokemon.body_shiny
poke2.debug_shiny = true if pokemon.debug_shiny && poke2.head_shiny
pokemon.body_shiny = false
pokemon.head_shiny = false
if !pokemon.shiny?
pokemon.debug_shiny = false
end
if !poke2.shiny?
poke2.debug_shiny = false
end
if $Trainer.party.length >= 6
if (keepInParty == 0)
if isOnPinkanIsland()
scene.pbDisplay(_INTL("{1} was released.", poke2.name))
else
$PokemonStorage.pbStoreCaught(poke2)
scene.pbDisplay(_INTL("{1} was sent to the PC.", poke2.name))
end
else
poke2 = Pokemon.new(bodyPoke, body_level)
poke1 = Pokemon.new(headPoke, head_level)
# Fusing from PC
if pcPosition != nil
box = pcPosition[0]
index = pcPosition[1]
# todo: store at next available position from current position
$PokemonStorage.pbStoreCaught(poke2)
else
# Fusing from party
if isOnPinkanIsland()
scene.pbDisplay(_INTL("{1} was released.", poke2.name))
else
$PokemonStorage.pbStoreCaught(poke2)
scene.pbDisplay(_INTL("{1} was sent to the PC.", poke2.name))
end
end
end
else
if pcPosition != nil
box = pcPosition[0]
index = pcPosition[1]
# todo: store at next available position from current position
$PokemonStorage.pbStoreCaught(poke2)
else
Kernel.pbAddPokemonSilent(poke2, poke2.level)
end
end
# On ajoute les poke au pokedex
$Trainer.pokedex.set_seen(poke1.species)
$Trainer.pokedex.set_owned(poke1.species)
$Trainer.pokedex.set_seen(poke2.species)
$Trainer.pokedex.set_owned(poke2.species)
pokemon.species = poke1.species
pokemon.level = poke1.level
pokemon.name = poke1.name
pokemon.moves = poke1.moves
pokemon.obtain_method = 0
poke1.obtain_method = 0
# scene.pbDisplay(_INTL(p1.to_s + " " + p2.to_s))
scene.pbHardRefresh
scene.pbDisplay(_INTL("Your Pokémon were successfully unfused! "))
return true
end
end
end# frozen_string_literal: true
def returnItemsToBag(pokemon, poke2)
it1 = pokemon.item
it2 = poke2.item
$PokemonBag.pbStoreItem(it1, 1) if it1 != nil
$PokemonBag.pbStoreItem(it2, 1) if it2 != nil
pokemon.item = nil
poke2.item = nil
end

View File

@@ -0,0 +1,403 @@
# module GameData
# class FusedSpecies < GameData::Species
# attr_reader :growth_rate
# attr_reader :body_pokemon
# attr_reader :head_pokemon
#
# def initialize(id)
# if id.is_a?(Integer)
# body_id = getBodyID(id)
# head_id = getHeadID(id, body_id)
# pokemon_id = getFusedPokemonIdFromDexNum(body_id, head_id)
# return GameData::FusedSpecies.new(pokemon_id)
# end
# head_id = get_head_number_from_symbol(id)
# body_id = get_body_number_from_symbol(id)
#
# @body_pokemon = GameData::Species.get(body_id)
# @head_pokemon = GameData::Species.get(head_id)
#
# @id = id
# @id_number = calculate_dex_number()
# @species = @id
# @form = 0
# @real_name = calculate_name()
# @real_form_name = nil
#
# @type1 = calculate_type1()
# @type2 = calculate_type2()
#
# #Stats
# @base_stats = calculate_base_stats()
# @evs = calculate_evs()
# adjust_stats_with_evs()
#
# @base_exp = calculate_base_exp()
# @growth_rate = calculate_growth_rate()
# @gender_ratio = calculate_gender() #todo
# @catch_rate = calculate_catch_rate()
# @happiness = calculate_base_happiness()
#
# #Moves
# @moves = calculate_moveset()
# @tutor_moves = calculate_tutor_moves() # hash[:tutor_moves] || []
# @egg_moves = calculate_egg_moves() # hash[:egg_moves] || []
#
# #Abilities
# @abilities = calculate_abilities() # hash[:abilities] || []
# @hidden_abilities = calculate_hidden_abilities() # hash[:hidden_abilities] || []
#
# #wild held items
# @wild_item_common = get_wild_item(@head_pokemon.wild_item_common, @body_pokemon.wild_item_common) # hash[:wild_item_common]
# @wild_item_uncommon = get_wild_item(@head_pokemon.wild_item_uncommon, @body_pokemon.wild_item_uncommon) # hash[:wild_item_uncommon]
# @wild_item_rare = get_wild_item(@head_pokemon.wild_item_rare, @body_pokemon.wild_item_rare) # hash[:wild_item_rare]
#
# @evolutions = calculate_evolutions() # hash[:evolutions] || []
#
# #breeding
# @egg_groups = [:Undiscovered] #calculate_egg_groups() # hash[:egg_groups] || [:Undiscovered]
# @hatch_steps = calculate_hatch_steps() # hash[:hatch_steps] || 1
# @incense = nil #hash[:incense]
#
# #pokedex
# @pokedex_form = @form #ignored
# @real_category = calculate_category()
# @real_pokedex_entry = calculate_dex_entry()
# @height = average_values(@head_pokemon.height, @body_pokemon.height)
# @weight = average_values(@head_pokemon.weight, @body_pokemon.weight)
# @color = @head_pokemon.color
# @shape = @body_pokemon.shape
#
# #sprite positioning
# @back_sprite_x = @body_pokemon.back_sprite_x
# @back_sprite_y = @body_pokemon.back_sprite_y
# @front_sprite_x = @body_pokemon.front_sprite_x
# @front_sprite_y = @body_pokemon.front_sprite_y
# @front_sprite_altitude = @body_pokemon.front_sprite_altitude
# @shadow_x = @body_pokemon.shadow_x
# @shadow_size = @body_pokemon.shadow_size
#
# # #unused attributes from Species class
# #
# # @shape = :Head
# # @habitat = :None
# # @generation = 0
# # @mega_stone = nil
# # @mega_move = nil
# # @unmega_form = 0
# # @mega_message = 0
# end
#
# def get_body_number_from_symbol(id)
# return id.to_s.match(/\d+/)[0].to_i
# end
#
# def get_head_number_from_symbol(id)
# return id.to_s.match(/(?<=H)\d+/)[0].to_i
# end
#
# def get_body_species
# return @body_pokemon.id_number
# end
#
# def get_head_species
# return @head_pokemon.id_number
# end
#
# def get_body_species_symbol
# return @body_pokemon.id
# end
#
# def get_head_species_symbol
# return @head_pokemon.id
# end
#
# def adjust_stats_with_evs
# GameData::Stat.each_main do |s|
# @base_stats[s.id] = 1 if !@base_stats[s.id] || @base_stats[s.id] <= 0
# @evs[s.id] = 0 if !@evs[s.id] || @evs[s.id] < 0
# end
# end
#
# #FUSION CALCULATIONS
# def calculate_dex_number()
# return (@body_pokemon.id_number * NB_POKEMON) + @head_pokemon.id_number
# end
#
# def calculate_type1()
# return @head_pokemon.type2 if @head_pokemon.type1 == :NORMAL && @head_pokemon.type2 == :FLYING
# return @head_pokemon.type1
# end
#
# def calculate_type2()
# return @body_pokemon.type1 if @body_pokemon.type2 == @type1
# return @body_pokemon.type2
# end
#
# def calculate_base_stats()
# head_stats = @head_pokemon.base_stats
# body_stats = @body_pokemon.base_stats
#
# fused_stats = {}
#
# #Head dominant stats
# fused_stats[:HP] = calculate_fused_stats(head_stats[:HP], body_stats[:HP])
# fused_stats[:SPECIAL_DEFENSE] = calculate_fused_stats(head_stats[:SPECIAL_DEFENSE], body_stats[:SPECIAL_DEFENSE])
# fused_stats[:SPECIAL_ATTACK] = calculate_fused_stats(head_stats[:SPECIAL_ATTACK], body_stats[:SPECIAL_ATTACK])
#
# #Body dominant stats
# fused_stats[:ATTACK] = calculate_fused_stats(body_stats[:ATTACK], head_stats[:ATTACK])
# fused_stats[:DEFENSE] = calculate_fused_stats(body_stats[:DEFENSE], head_stats[:DEFENSE])
# fused_stats[:SPEED] = calculate_fused_stats(body_stats[:SPEED], head_stats[:SPEED])
#
# return fused_stats
# end
#
# def calculate_base_exp()
# head_exp = @head_pokemon.base_exp
# body_exp = @body_pokemon.base_exp
# return average_values(head_exp, body_exp)
# end
#
# def calculate_catch_rate
# return get_lowest_value(@body_pokemon.catch_rate, @head_pokemon.catch_rate)
# end
#
# def calculate_base_happiness
# return @head_pokemon.happiness
# end
#
# def calculate_moveset
# return combine_arrays(@body_pokemon.moves, @head_pokemon.moves)
# end
#
# def calculate_egg_moves
# return combine_arrays(@body_pokemon.egg_moves, @head_pokemon.egg_moves)
# end
#
# def calculate_tutor_moves
# return combine_arrays(@body_pokemon.tutor_moves, @head_pokemon.tutor_moves)
# end
#
# def get_wild_item(body_item, head_item)
# rand_num = rand(2)
# if rand_num == 0
# return body_item
# else
# return head_item
# end
# end
#
# def calculate_abilities()
# abilities_hash = []
#
# ability1 = @body_pokemon.abilities[0]
# ability2 = @head_pokemon.abilities[0]
# abilities_hash << ability1
# abilities_hash << ability2
# return abilities_hash
# end
#
# # def calculate_abilities(pokemon1, pokemon2)
# # abilities_hash = []
# #
# # ability1 = pokemon1.abilities[0]
# # ability2 = pokemon2.abilities[1]
# # if !ability2
# # ability2 = pokemon2.abilities[0]
# # end
# # abilities_hash << ability1
# # abilities_hash << ability2
# # return abilities_hash
# # end
#
# def calculate_hidden_abilities()
# abilities_hash = []
#
# #First two spots are the other abilities of the two pokemon
# ability1 = @body_pokemon.abilities[1]
# ability2 = @head_pokemon.abilities[1]
# ability1 = @body_pokemon.abilities[0] if !ability1
# ability2 = @head_pokemon.abilities[0] if !ability2
#
# abilities_hash << ability1
# abilities_hash << ability2
#
# #add the hidden ability for the two base pokemon
# hiddenAbility1 = @body_pokemon.hidden_abilities[0]
# hiddenAbility1 = ability1 if !hiddenAbility1
#
# hiddenAbility2 = @head_pokemon.hidden_abilities[0]
# hiddenAbility2 = ability2 if !hiddenAbility2
#
# abilities_hash << hiddenAbility1
# abilities_hash << hiddenAbility2
# return abilities_hash
# end
#
# def calculate_name()
# body_nat_dex = GameData::NAT_DEX_MAPPING[@body_pokemon.id_number] ? GameData::NAT_DEX_MAPPING[@body_pokemon.id_number] : @body_pokemon.id_number
# head_nat_dex = GameData::NAT_DEX_MAPPING[@head_pokemon.id_number] ? GameData::NAT_DEX_MAPPING[@head_pokemon.id_number] : @head_pokemon.id_number
# begin
# prefix = GameData::SPLIT_NAMES[head_nat_dex][0]
# suffix = GameData::SPLIT_NAMES[body_nat_dex][1]
# if prefix[-1] == suffix[0]
# prefix = prefix[0..-2]
# end
# suffix = suffix.capitalize if prefix.end_with?(" ")
# return prefix + suffix
#
# rescue
# print("species with error: " + @species.to_s)
# end
#
# end
#
# def calculate_evolutions()
# body_evolutions = @body_pokemon.evolutions
# head_evolutions = @head_pokemon.evolutions
#
# fused_evolutions = []
#
# #body
# for evolution in body_evolutions
# evolutionSpecies = evolution[0]
# evolutionSpecies_dex = GameData::Species.get(evolutionSpecies).id_number
# fused_species = _INTL("B{1}H{2}", evolutionSpecies_dex, @head_pokemon.id_number)
# fused_evolutions << build_evolution_array(evolution, fused_species)
# end
#
# #head
# for evolution in head_evolutions
# evolutionSpecies = evolution[0]
# evolutionSpecies_dex = GameData::Species.get(evolutionSpecies).id_number
# fused_species = _INTL("B{1}H{2}", @body_pokemon.id_number, evolutionSpecies_dex)
# fused_evolutions << build_evolution_array(evolution, fused_species)
# end
#
# return fused_evolutions
# end
#
# #Change the evolution species depending if head & body and keep the rest of the data the same
# def build_evolution_array(evolution_data, new_species)
# fused_evolution_array = []
# fused_evolution_array << new_species.to_sym
#
# #add the rest
# for data in evolution_data
# next if evolution_data.index(data) == 0
# fused_evolution_array << data
# end
# return fused_evolution_array
# end
#
# def calculate_dex_entry
# body_entry = @body_pokemon.real_pokedex_entry.gsub(@body_pokemon.real_name, @real_name)
# head_entry = @head_pokemon.real_pokedex_entry.gsub(@head_pokemon.real_name, @real_name)
#
# return split_and_combine_text(body_entry, head_entry, ".")
# end
#
# def get_random_dex_entry()
# begin
# file_path = Settings::POKEDEX_ENTRIES_PATH
# json_data = File.read(file_path)
# all_body_entries = HTTPLite::JSON.parse(json_data)
#
#
# body_entry = all_body_entries[@body_pokemon.id_number.to_s].sample
# body_entry = body_entry.gsub(/#{@body_pokemon.real_name}/i, @real_name)
# body_entry = clean_json_string(body_entry).gsub(@body_pokemon.real_name, @real_name)
#
# head_entry = all_body_entries[@head_pokemon.id_number.to_s].sample
# head_entry = head_entry.gsub(/#{@head_pokemon.real_name}/i, @real_name)
# head_entry = clean_json_string(head_entry).gsub(@head_pokemon.real_name, @real_name)
# rescue
# body_entry = @body_pokemon.real_pokedex_entry.gsub(@body_pokemon.real_name, @real_name)
# head_entry = @head_pokemon.real_pokedex_entry.gsub(@head_pokemon.real_name, @real_name)
# end
# echoln body_entry
# echoln head_entry
# combined_entry = split_and_combine_text(body_entry, head_entry, ".")
# combined_entry += "." unless combined_entry.end_with?(".")
# return combined_entry
# end
#
# def calculate_egg_groups
# body_egg_groups = @body_pokemon.egg_groups
# head_egg_groups = @head_pokemon.egg_groups
# return :Undiscovered if body_egg_groups.include?(:Undiscovered) || head_egg_groups.include?(:Undiscovered)
# return combine_arrays(body_egg_groups, head_egg_groups)
# end
#
# def calculate_hatch_steps
# return average_values(@head_pokemon.hatch_steps, @body_pokemon.hatch_steps)
# end
#
# def calculate_evs()
# return average_map_values(@body_pokemon.evs, @head_pokemon.evs)
# end
#
# def calculate_category
# return split_and_combine_text(@body_pokemon.category, @head_pokemon.category, " ")
# end
#
# def calculate_growth_rate
# growth_rate_priority = [:Fast, :Medium, :Parabolic, :Fluctuating, :Erratic, :Slow] #todo rearrange order for balance?
# body_growth_rate = @body_pokemon.growth_rate
# head_growth_rate = @head_pokemon.growth_rate
# base_growth_rates = [body_growth_rate, head_growth_rate]
# for rate in growth_rate_priority
# return rate if base_growth_rates.include?(rate)
# end
# return :Medium
# end
#
# #TODO
# # ################## UNFINISHED ####################
# def calculate_gender
# return :Genderless
# end
#
# ############################# UTIL METHODS ###############################
#
# #Takes 2 strings, splits and combines them using the beginning of the first one and the end of the second one
# # (for example for pokedex entries)
# def split_and_combine_text(beginingText_full, endText_full, separator)
# beginingText_split = beginingText_full.split(separator, 2)
# endText_split = endText_full.split(separator, 2)
#
# beginningText = beginingText_split[0]
# endText = endText_split[1] && endText_split[1] != "" ? endText_split[1] : endText_split[0]
# return beginningText + separator + " " + endText
# end
#
# def calculate_fused_stats(dominantStat, otherStat)
# return ((2 * dominantStat) / 3) + (otherStat / 3).floor
# end
#
# def average_values(value1, value2)
# return ((value1 + value2) / 2).floor
# end
#
# def average_map_values(map1, map2)
# averaged_map = map1.merge(map2) do |key, value1, value2|
# ((value1 + value2) / 2.0).floor
# end
# return averaged_map
# end
#
# def get_highest_value(value1, value2)
# return value1 > value2 ? value1 : value2
# end
#
# def get_lowest_value(value1, value2)
# return value1 < value2 ? value1 : value2
# end
#
# def combine_arrays(array1, array2)
# return array1 + array2
# end
#
# end
# end

View File

@@ -0,0 +1,31 @@
# module GameData
# module ClassMethods
# def get(other)
# validate other => [Symbol, self, String, Integer]
# return other if other.is_a?(self)
# other = other.to_sym if other.is_a?(String)
#
# if other.to_s.match?(/\AB\d+H\d+\z/)
# species = GameData::FusedSpecies.new(other)
# return species
# end
#
# if other.is_a?(Integer) && self == GameData::Species
# if other > NB_POKEMON
# body_id = getBodyID(other)
# head_id = getHeadID(other, body_id)
# pokemon_id = getFusedPokemonIdFromDexNum(body_id, head_id)
# return GameData::FusedSpecies.new(pokemon_id)
# end
# end
#
# if !self::DATA.has_key?(other)
# # echoln _INTL("Unknown ID {1}.", other)
# return self::get(:PIKACHU)
# end
#
# raise "Unknown ID #{other}." unless self::DATA.has_key?(other)
# return self::DATA[other]
# end
# end
# end

View File

@@ -0,0 +1,410 @@
def is_fusion_of_any(species_id, pokemonList)
is_species = false
for fusionPokemon in pokemonList
if is_fusion_of(species_id, fusionPokemon)
is_species = true
end
end
return is_species
end
def is_fusion_of(checked_species, checked_against)
return species_has_body_of(checked_species, checked_against) || species_has_head_of(checked_species, checked_against)
end
def is_species(checked_species, checked_against)
return checked_species == checked_against
end
def species_has_body_of(checked_species, checked_against)
if !species_is_fusion(checked_species)
return is_species(checked_species, checked_against)
end
bodySpecies = get_body_species_from_symbol(checked_species)
ret = bodySpecies == checked_against
#echoln _INTL("{1} HAS BODY OF {2} : {3} (body is {4})",checked_species,checked_against,ret,bodySpecies)
return ret
end
def species_has_head_of(checked_species, checked_against)
if !species_is_fusion(checked_species)
return is_species(checked_species, checked_against)
end
headSpecies = get_head_species_from_symbol(checked_species)
ret = headSpecies == checked_against
#echoln _INTL("{1} HAS HEAD OF {2} : {3}",checked_species,checked_against,ret)
return ret
end
def species_is_fusion(species_id)
dex_number = get_dex_number(species_id)
return dex_number > NB_POKEMON && dex_number < Settings::ZAPMOLCUNO_NB
end
def get_dex_number(species_id)
return GameData::Species.get(species_id).id_number
end
def getBodyID(species, nb_pokemon = NB_POKEMON)
if species.is_a?(Integer)
dexNum = species
else
dexNum = getDexNumberForSpecies(species)
end
if dexNum % nb_pokemon == 0
return (dexNum / nb_pokemon) - 1
end
return (dexNum / nb_pokemon).round
end
def getHeadID(species, bodyId = nil, nb_pokemon = NB_POKEMON)
if species.is_a?(Integer)
fused_dexNum = species
else
fused_dexNum = getDexNumberForSpecies(species)
end
if bodyId == nil
bodyId = getBodyID(species)
end
body_dexNum = getDexNumberForSpecies(bodyId)
calculated_number = (fused_dexNum - (body_dexNum * nb_pokemon)).round
return calculated_number == 0 ? nb_pokemon : calculated_number
end
def get_fusion_id(head_number, body_number)
return "B#{body_number}H#{head_number}".to_sym
end
def get_body_id_from_symbol(id)
split_id = id.to_s.match(/\d+/)
if !split_id #non-fusion
return GameData::Species.get(id).id_number
end
return split_id[0].to_i
end
def get_head_id_from_symbol(id)
split_id = id.to_s.match(/(?<=H)\d+/)
if !split_id #non-fusion
return GameData::Species.get(id).id_number
end
return split_id[0].to_i
end
def obtainPokemonSpritePath(id, includeCustoms = true)
head = getBasePokemonID(param.to_i, false)
body = getBasePokemonID(param.to_i, true)
return obtainPokemonSpritePath(body, head, includeCustoms)
end
def obtainPokemonSpritePath(bodyId, headId, include_customs = true)
#download_pokemon_sprite_if_missing(bodyId, headId)
picturePath = _INTL("Graphics/Battlers/{1}/{1}.{2}.png", headId, bodyId)
if include_customs && customSpriteExistsBodyHead(bodyId, headId)
pathCustom = getCustomSpritePath(bodyId, headId)
if (pbResolveBitmap(pathCustom))
picturePath = pathCustom
end
end
return picturePath
end
def getCustomSpritePath(body, head)
return _INTL("#{Settings::CUSTOM_BATTLERS_FOLDER_INDEXED}{1}/{1}.{2}.png", head, body)
end
def customSpriteExistsForm(species, form_id_head = nil, form_id_body = nil)
head = getBasePokemonID(species, false)
body = getBasePokemonID(species, true)
folder = head.to_s
folder += "_" + form_id_head.to_s if form_id_head
spritename = head.to_s
spritename += "_" + form_id_head.to_s if form_id_head
spritename += "." + body.to_s
spritename += "_" + form_id_body.to_s if form_id_body
pathCustom = _INTL("Graphics/.CustomBattlers/indexed/{1}/{2}.png", folder, spritename)
return true if pbResolveBitmap(pathCustom) != nil
return download_custom_sprite(head, body) != nil
end
def get_fusion_spritename(head_id, body_id, alt_letter = "")
return "#{head_id}.#{body_id}#{alt_letter}"
end
def customSpriteExistsSpecies(species)
head = getBasePokemonID(species, false)
body = getBasePokemonID(species, true)
return customSpriteExists(body, head)
# pathCustom = getCustomSpritePath(body, head)
#
# return true if pbResolveBitmap(pathCustom) != nil
# return download_custom_sprite(head, body) != nil
end
def getRandomCustomFusion(returnRandomPokemonIfNoneFound = true, customPokeList = [], maxPoke = -1, recursionLimit = 3)
if customPokeList.length == 0
customPokeList = getCustomSpeciesList(false)
end
randPoke = []
if customPokeList.length >= 5000
chosen = false
i = 0 #loop pas plus que 3 fois pour pas lag
while chosen == false
fusedPoke = customPokeList[rand(customPokeList.length)]
poke1 = getBasePokemonID(fusedPoke, false)
poke2 = getBasePokemonID(fusedPoke, true)
if ((poke1 <= maxPoke && poke2 <= maxPoke) || i >= recursionLimit) || maxPoke == -1
randPoke << getBasePokemonID(fusedPoke, false)
randPoke << getBasePokemonID(fusedPoke, true)
chosen = true
end
end
else
if returnRandomPokemonIfNoneFound
randPoke << rand(maxPoke) + 1
randPoke << rand(maxPoke) + 1
end
end
return randPoke
end
def checkIfCustomSpriteExistsByPath(path)
return true if pbResolveBitmap(path) != nil
end
def customSpriteExistsBodyHead(body, head)
pathCustom = getCustomSpritePath(body, head)
return true if pbResolveBitmap(pathCustom) != nil
return download_custom_sprite(head, body) != nil
end
def customSpriteExistsSpecies(species)
body_id = getBodyID(species)
head_id = getHeadID(species, body_id)
fusion_id = get_fusion_symbol(head_id, body_id)
return $game_temp.custom_sprites_list.include?(fusion_id)
end
def customSpriteExists(body, head)
fusion_id = get_fusion_symbol(head, body)
return $game_temp.custom_sprites_list.include?(fusion_id)
end
#shortcut for using in game events because of script characters limit
def dexNum(species)
return getDexNumberForSpecies(species)
end
def isTripleFusion?(num)
return num >= Settings::ZAPMOLCUNO_NB
end
def isFusion(num)
return num > Settings::NB_POKEMON && !isTripleFusion?(num)
end
def isSpeciesFusion(species)
num = getDexNumberForSpecies(species)
return isFusion(num)
end
def getRandomLocalFusion()
spritesList = []
$PokemonGlobal.alt_sprite_substitutions.each_value do |value|
if value.is_a?(PIFSprite)
spritesList << value
end
end
return spritesList.sample
end
def getRandomFusionForIntro()
random_pokemon = $game_temp.custom_sprites_list.keys.sample || :PIKACHU
alt_letter = $game_temp.custom_sprites_list[random_pokemon]
body_id = get_body_number_from_symbol(random_pokemon)
head_id = get_head_number_from_symbol(random_pokemon)
return PIFSprite.new(:CUSTOM, head_id, body_id, alt_letter)
end
def getSpeciesIdForFusion(head_number, body_number)
return (body_number) * Settings::NB_POKEMON + head_number
end
def get_body_species_from_symbol(fused_id)
body_num = get_body_number_from_symbol(fused_id)
return GameData::Species.get(body_num).species
end
def get_head_species_from_symbol(fused_id)
head_num = get_head_number_from_symbol(fused_id)
return GameData::Species.get(head_num).species
end
def get_body_number_from_symbol(id)
dexNum = getDexNumberForSpecies(id)
return dexNum if !isFusion(dexNum)
id.to_s.match(/\d+/)[0]
return id.to_s.match(/\d+/)[0].to_i
end
def get_head_number_from_symbol(id)
dexNum = getDexNumberForSpecies(id)
return dexNum if !isFusion(dexNum)
return id.to_s.match(/(?<=H)\d+/)[0].to_i
end
def get_fusion_symbol(head_id, body_id)
return "B#{body_id}H#{head_id}".to_sym
end
def getFusionSpecies(body, head)
body_num = getDexNumberForSpecies(body)
head_num = getDexNumberForSpecies(head)
id = body_num * Settings::NB_POKEMON + head_num
return GameData::Species.get(id)
end
def getDexNumberForSpecies(species)
return species if species.is_a?(Integer)
if species.is_a?(Symbol)
dexNum = GameData::Species.get(species).id_number
elsif species.is_a?(Pokemon)
dexNum = GameData::Species.get(species.species).id_number
elsif species.is_a?(GameData::Species)
return species.id_number
else
dexNum = species
end
return dexNum
end
def getFusedPokemonIdFromDexNum(body_dex, head_dex)
return ("B" + body_dex.to_s + "H" + head_dex.to_s).to_sym
end
def getFusedPokemonIdFromSymbols(body_dex, head_dex)
bodyDexNum = GameData::Species.get(body_dex).id_number
headDexNum = GameData::Species.get(head_dex).id_number
return getFusedPokemonIdFromDexNum(bodyDexNum, headDexNum)
end
def generateFusionIcon(dexNum, path)
begin
IO.copy_stream(dexNum, path)
return true
rescue
return false
end
end
def ensureFusionIconExists
directory_name = "Graphics/Pokemon/FusionIcons"
Dir.mkdir(directory_name) unless File.exists?(directory_name)
end
def addNewTripleFusion(pokemon1, pokemon2, pokemon3, level = 1)
return if !pokemon1
return if !pokemon2
return if !pokemon3
if pbBoxesFull?
pbMessage(_INTL("There's no more room for Pokémon!\1"))
pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
return false
end
pokemon = TripleFusion.new(pokemon1, pokemon2, pokemon3, level)
pokemon.calc_stats
pbMessage(_INTL("{1} obtained {2}!\\me[Pkmn get]\\wtnp[80]\1", $Trainer.name, pokemon.name))
pbNicknameAndStore(pokemon)
#$Trainer.pokedex.register(pokemon)
return true
end
def get_triple_fusion_components(species_id)
dex_num = GameData::Species.get(species_id).id_number
case dex_num
when Settings::ZAPMOLCUNO_NB
return [144,145,146]
when Settings::ZAPMOLCUNO_NB + 1
return [144,145,146]
when Settings::ZAPMOLCUNO_NB + 2
return [243,244,245]
when Settings::ZAPMOLCUNO_NB + 3
return [340,341,342]
when Settings::ZAPMOLCUNO_NB + 4
return [343,344,345]
when Settings::ZAPMOLCUNO_NB + 5
return [349,350,351]
when Settings::ZAPMOLCUNO_NB + 6
return [151,251,381]
when Settings::ZAPMOLCUNO_NB + 11
return [150,348,380]
#starters
when Settings::ZAPMOLCUNO_NB + 7
return [3,6,9]
when Settings::ZAPMOLCUNO_NB + 8
return [154,157,160]
when Settings::ZAPMOLCUNO_NB + 9
return [278,281,284]
when Settings::ZAPMOLCUNO_NB + 10
return [318,321,324]
#starters prevos
when Settings::ZAPMOLCUNO_NB + 12
return [1,4,7]
when Settings::ZAPMOLCUNO_NB + 13
return [2,5,8]
when Settings::ZAPMOLCUNO_NB + 14
return [152,155,158]
when Settings::ZAPMOLCUNO_NB + 15
return [153,156,159]
when Settings::ZAPMOLCUNO_NB + 16
return [276,279,282]
when Settings::ZAPMOLCUNO_NB + 17
return [277,280,283]
when Settings::ZAPMOLCUNO_NB + 18
return [316,319,322]
when Settings::ZAPMOLCUNO_NB + 19
return [317,320,323]
when Settings::ZAPMOLCUNO_NB + 20 #birdBoss Left
return []
when Settings::ZAPMOLCUNO_NB + 21 #birdBoss middle
return [144,145,146]
when Settings::ZAPMOLCUNO_NB + 22 #birdBoss right
return []
when Settings::ZAPMOLCUNO_NB + 23 #sinnohboss left
return []
when Settings::ZAPMOLCUNO_NB + 24 #sinnohboss middle
return [343,344,345]
when Settings::ZAPMOLCUNO_NB + 25 #sinnohboss right
return []
when Settings::ZAPMOLCUNO_NB + 25 #cardboard
return []
when Settings::ZAPMOLCUNO_NB + 26 #cardboard
return []
when Settings::ZAPMOLCUNO_NB + 27 #Triple regi
return [447,448,449]
#Triple Kalos 1
when Settings::ZAPMOLCUNO_NB + 28
return [479,482,485]
when Settings::ZAPMOLCUNO_NB + 29
return [480,483,486]
when Settings::ZAPMOLCUNO_NB + 30
return [481,484,487]
else
return [000]
end
end

View File

@@ -0,0 +1,29 @@
# frozen_string_literal: true
def pokemart_clothes_shop(current_city = nil, include_defaults = true)
current_city = pbGet(VAR_CURRENT_MART) if !current_city
echoln current_city
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
selector = OutfitSelector.new
list = selector.generate_clothes_choice(
baseOptions = include_defaults,
additionalIds = [],
additionalTags = [current_city_tag],
filterOutTags = [])
clothesShop(list)
end
def pokemart_hat_shop(include_defaults = true)
current_city = pbGet(VAR_CURRENT_MART)
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
selector = OutfitSelector.new
list = selector.generate_hats_choice(
baseOptions = include_defaults,
additionalIds = [],
additionalTags = [current_city_tag],
filterOutTags = [])
hatShop(list)
end

View File

@@ -0,0 +1,53 @@
def get_mart_exclusive_items(city)
items_list = []
case city
when :PEWTER;
items_list = [:ROCKGEM, :NESTBALL]
when :VIRIDIAN;
items_list = []
when :CERULEAN;
items_list = [:WATERGEM, :NETBALL, :PRETTYWING]
when :VERMILLION;
items_list = [:LOVEBALL, :ELECTRICGEM]
when :LAVENDER;
items_list = [:GHOSTGEM, :DARKGEM, :DUSKBALL]
when :CELADON;
items_list = [:GRASSGEM, :FLYINGGEM, :QUICKBALL, :TIMERBALL,]
when :FUCHSIA;
items_list = [:POISONGEM, :REPEATBALL]
when :SAFFRON;
items_list = [:PSYCHICGEM, :FIGHTINGGEM, :FRIENDBALL]
when :CINNABAR;
items_list = [:FIREGEM, :ICEGEM, :HEAVYBALL]
when :CRIMSON;
items_list = [:DRAGONGEM, :LEVELBALL]
when :GOLDENROD;
items_list = [:EVERSTONE, :MOONSTONE, :SUNSTONE, :DUSKSTONE, :DAWNSTONE, :SHINYSTONE]
when :AZALEA;
items_list = [:BUGGEM]
when :VIOLET;
items_list = [:FLYINGGEM, :STATUSBALL]
when :BLACKTHORN;
items_list = [:DRAGONGEM, :CANDYBALL]
when :CHERRYGROVE;
items_list = [:BUGGEM, :PUREBALL]
when :MAHOGANY;
items_list = []
when :ECRUTEAK;
items_list = [:GHOSTGEM, :DARKGEM]
when :OLIVINE;
items_list = []
when :CIANWOOD;
items_list = []
when :KNOTISLAND;
items_list = []
when :BOONISLAND;
items_list = []
when :KINISLAND;
items_list = []
when :CHRONOISLAND;
items_list = []
end
return items_list
end# frozen_string_literal: true

View File

@@ -0,0 +1,87 @@
# frozen_string_literal: true
# Necessary dor setting the various events within the pokemart map, uses the numbers as wondertrade
def get_city_numerical_id(city_sym)
current_city_numerical = {
:PEWTER => 1,
:CERULEAN => 2,
:VERMILLION => 3,
:LAVENDER => 4,
:CELADON => 5,
:FUCHSIA => 6,
:SAFFRON => 7,
:CINNABAR => 8,
:LEAGUE => 9,
:VIOLET => 10,
:AZALEA => 11,
:GOLDENROD => 12,
:ECRUTEAK => 13,
:MAHOGANY => 14,
:BLACKTHORN => 15,
:OLIVINE => 16,
:CIANWOOD => 17,
:KNOTISLAND => 18,
:BOONISLAND => 19,
:KINISLAND => 20,
:CHRONOISLAND => 21,
:CRIMSON => 22,
}
return current_city_numerical[city_sym]
end
POKEMART_MAP_ID = 357
POKEMART_DOOR_POS = [12, 12]
# city -> Symbol
def enter_pokemart(city)
pbSet(VAR_CURRENT_MART, city)
pbSet(VAR_CURRENT_CITY_NUMERICAL_ID, get_city_numerical_id(city))
echoln get_city_numerical_id(city)
pbFadeOutIn {
$game_temp.player_new_map_id = POKEMART_MAP_ID
$game_temp.player_new_x = POKEMART_DOOR_POS[0]
$game_temp.player_new_y = POKEMART_DOOR_POS[1]
$scene.transfer_player(true)
$game_map.autoplay
$game_map.refresh
}
end
def exit_pokemart()
pokemart_entrances = {
:PEWTER => [380, 43, 24],
:CERULEAN => [1, 24, 22],
:VERMILLION => [19, 32, 13],
:LAVENDER => [50, 20, 23],
:CELADON => [95, 18, 15], # not a real pokemart
:FUCHSIA => [472, 7, 17],
:SAFFRON => [108, 53, 24],
:CINNABAR => [98, 30, 30],
:CRIMSON => [167, 21, 36],
:GOLDENROD => [237, 36, 33], # not a real pokemart
:AZALEA => [278, 34, 17],
:AZALEA_FLOODED => [338, 34, 17],
:VIOLET => [230, 20, 31],
:BLACKTHORN => [329, 16, 36],
:MAHOGANY => [631, 19, 19], # not a real pokemart
:ECRUTEAK => [359, 46, 38],
:OLIVINE => [138, 33, 23],
:CIANWOOD => [709.8, 46],
}
current_city = pbGet(VAR_CURRENT_MART)
current_city = :PEWTER if !current_city.is_a?(Symbol)
entrance_map = pokemart_entrances[current_city][0]
entrance_x = pokemart_entrances[current_city][1]
entrance_y = pokemart_entrances[current_city][2]
pbSet(VAR_CURRENT_CITY_NUMERICAL_ID, 0)
pbSet(VAR_CURRENT_MART, 0)
pbFadeOutIn {
$game_temp.player_new_map_id = entrance_map
$game_temp.player_new_x = entrance_x
$game_temp.player_new_y = entrance_y
$scene.transfer_player(true)
$game_map.autoplay
$game_map.refresh
}
end

View File

@@ -0,0 +1,38 @@
def turnEventTowardsEvent(turning, turnedTowards)
event_x = turnedTowards.x
event_y = turnedTowards.y
if turning.x < event_x
turning.turn_right # Event is to the right of the player
elsif turning.x > event_x
turning.turn_left # Event is to the left of the player
elsif turning.y < event_y
turning.turn_down # Event is below the player
elsif turning.y > event_y
turning.turn_up # Event is above the player
end
end
def turnPlayerTowardsEvent(event)
event_x = event.x
event_y = event.y
if $game_player.x < event_x
$game_player.turn_right # Event is to the right of the player
elsif $game_player.x > event_x
$game_player.turn_left # Event is to the left of the player
elsif $game_player.y < event_y
$game_player.turn_down # Event is below the player
elsif $game_player.y > event_y
$game_player.turn_up # Event is above the player
end
end
def player_near_event?(map_id, event_id, radius)
return false if map_id != $game_map.map_id
event = $game_map.events[event_id]
return false if event.nil?
dx = $game_player.x - event.x
dy = $game_player.y - event.y
distance = Math.sqrt(dx * dx + dy * dy)
return distance <= radius
end

View File

@@ -0,0 +1,6 @@
def has_species_or_fusion?(species, form = -1)
return $Trainer.pokemon_party.any? { |p| p && p.isSpecies?(species) || p.isFusionOf(species) }
end
# frozen_string_literal: true

View File

@@ -0,0 +1,563 @@
def getAllCurrentlyRoamingPokemon
currently_roaming = []
Settings::ROAMING_SPECIES.each_with_index do |data, i|
next if !GameData::Species.exists?(data[0])
next if data[2] > 0 && !$game_switches[data[2]] # Isn't roaming
next if $PokemonGlobal.roamPokemon[i] == true # Roaming Pokémon has been caught
currently_roaming << i
end
return currently_roaming
end
def track_pokemon()
currently_roaming = getAllCurrentlyRoamingPokemon()
echoln currently_roaming
weather_data = []
mapinfos = $RPGVX ? load_data("Data/MapInfos.rvdata") : load_data("Data/MapInfos.rxdata")
currently_roaming.each do |roamer_id|
map_id = $PokemonGlobal.roamPosition[roamer_id]
map_name = mapinfos[map_id].name
weather_type = Settings::ROAMING_SPECIES[roamer_id][6]
case weather_type
when :Storm
forecast_msg = _INTL("An unusual \\c[6]thunderstorm\\c[0] has been detected around \\c[6]{1}", map_name)
when :StrongWinds
forecast_msg = _INTL("Unusually \\c[9]strong winds\\c[0] have been detected around \\c[9]{1}", map_name)
when :Sunny
forecast_msg = _INTL("Unusually \\c[10]harsh sunlight\\c[0] has been detected around \\c[10]{1}", map_name)
end
weather_data << forecast_msg if forecast_msg && !weather_data.include?(forecast_msg)
end
weather_data << _INTL("No unusual weather patterns have been detected.") if weather_data.empty?
weather_data.each do |message|
Kernel.pbMessage(message)
end
end
# frozen_string_literal: true
def getHiddenPowerName(pokemon)
hiddenpower = pbHiddenPower(pokemon)
hiddenPowerType = hiddenpower[0]
echoln hiddenPowerType
if Settings::TRIPLE_TYPES.include?(hiddenPowerType)
return "Neutral"
end
return PBTypes.getName(hiddenPowerType)
end
# Returns if the current map is an outdoor map
def isOutdoor()
current_map = $game_map.map_id
map_metadata = GameData::MapMetadata.try_get(current_map)
return map_metadata && map_metadata.outdoor_map
end
def qmarkMaskCheck()
if $Trainer.seen_qmarks_sprite
unless hasHat?(HAT_QMARKS)
obtainHat(HAT_QMARKS)
obtainClothes(CLOTHES_GLITCH)
end
end
end
def giveJigglypuffScribbles(possible_versions = [1,2,3,4])
selected_scribbles_version = possible_versions.sample
case selected_scribbles_version
when 1
scribbles_id= HAT_SCRIBBLES1
when 2
scribbles_id= HAT_SCRIBBLES2
when 3
scribbles_id= HAT_SCRIBBLES3
when 4
scribbles_id= HAT_SCRIBBLES4
end
return if !scribbles_id
if !hasHat?(scribbles_id)
$Trainer.unlocked_hats << scribbles_id
end
putOnHat(scribbles_id,true,true)
end
# chance: out of 100
def lilypadEncounter(pokemon, minLevel, maxLevel, chance = 10)
minLevel, maxLevel = [minLevel, maxLevel].minmax
level = rand(minLevel..maxLevel)
event = $game_map.events[@event_id]
return if !event
if rand(0..100) <= chance
pbWildBattle(pokemon, level)
else
playAnimation(Settings::GRASS_ANIMATION_ID, event.x, event.y)
end
event.erase
end
def calculate_pokemon_weight(pokemon, nerf = 0)
base_weight = pokemon.weight
ivs = []
pokemon.iv.each { |iv|
ivs << iv[1]
}
level = pokemon.level
# Ensure IVs is an array of 6 values and level is between 1 and 100
raise "IVs array must have 6 values" if ivs.length != 6
raise "Level must be between 1 and 100" unless (1..100).include?(level)
# Calculate the IV Factor
iv_sum = ivs.sum
iv_factor = (iv_sum.to_f / 186) * 30 * 10
# Calculate the Level Factor
level_factor = (level.to_f / 100) * 5 * 10
# Calculate the weight
weight = base_weight * (1 + (iv_factor / 100) + (level_factor / 100))
weight -= base_weight
# Enforce the weight variation limits
max_weight = base_weight * 4.00 # 400% increase
min_weight = base_weight * 0.5 # 50% decrease
# Cap the weight between min and max values
weight = [[weight, min_weight].max, max_weight].min
weight -= nerf if weight - nerf > min_weight
return weight.round(2) # Round to 2 decimal places
end
# nerf: remove x kg from each generated pokemon
def generate_weight_contest_entries(species, level, resultsVariable, nerf = 0)
# echoln "Generating Pokemon"
pokemon1 = pbGenerateWildPokemon(species, level) # Pokemon.new(species,level)
pokemon2 = pbGenerateWildPokemon(species, level) # Pokemon.new(species,level)
new_weights = []
new_weights << calculate_pokemon_weight(pokemon1, nerf)
new_weights << calculate_pokemon_weight(pokemon2, nerf)
echoln new_weights
echoln "(nerfed by -#{nerf})"
pbSet(resultsVariable, new_weights.max)
end
# time in seconds
def idleHatEvent(hatId, time, switchToActivate = nil)
map = $game_map.map_id
i = 0
while i < (time / 5) do
# /5 because we update 5 times per second
return if $game_map.map_id != map
i += 1
pbWait(4)
i = 0 if $game_player.moving?
echoln i
end
$game_switches[switchToActivate] = true if switchToActivate
obtainHat(hatId)
end
def obtainStarter(starterIndex = 0)
if ($game_switches[SWITCH_RANDOM_STARTERS])
starter = obtainRandomizedStarter(starterIndex)
else
startersList = Settings::KANTO_STARTERS
if $game_switches[SWITCH_JOHTO_STARTERS]
startersList = Settings::JOHTO_STARTERS
elsif $game_switches[SWITCH_HOENN_STARTERS]
startersList = Settings::HOENN_STARTERS
elsif $game_switches[SWITCH_SINNOH_STARTERS]
startersList = Settings::SINNOH_STARTERS
elsif $game_switches[SWITCH_KALOS_STARTERS]
startersList = Settings::KALOS_STARTERS
end
starter = startersList[starterIndex]
end
return GameData::Species.get(starter)
end
def isPostgame?()
return $game_switches[SWITCH_BEAT_THE_LEAGUE]
end
def constellation_add_star(pokemon)
star_variables = get_constellation_variable(pokemon)
pbSEPlay("GUI trainer card open", 80)
nb_stars = pbGet(star_variables)
pbSet(star_variables, nb_stars + 1)
end
def get_constellation_variable(pokemon)
case pokemon
when :IVYSAUR;
return VAR_CONSTELLATION_IVYSAUR
when :WARTORTLE;
return VAR_CONSTELLATION_WARTORTLE
when :ARCANINE;
return VAR_CONSTELLATION_ARCANINE
when :MACHOKE;
return VAR_CONSTELLATION_MACHOKE
when :RAPIDASH;
return VAR_CONSTELLATION_RAPIDASH
when :GYARADOS;
return VAR_CONSTELLATION_GYARADOS
when :ARTICUNO;
return VAR_CONSTELLATION_ARTICUNO
when :MEW;
return VAR_CONSTELLATION_MEW
# when :POLITOED; return VAR_CONSTELLATION_POLITOED
# when :URSARING; return VAR_CONSTELLATION_URSARING
# when :LUGIA; return VAR_CONSTELLATION_LUGIA
# when :HOOH; return VAR_CONSTELLATION_HOOH
# when :CELEBI; return VAR_CONSTELLATION_CELEBI
# when :SLAKING; return VAR_CONSTELLATION_SLAKING
# when :JIRACHI; return VAR_CONSTELLATION_JIRACHI
# when :TYRANTRUM; return VAR_CONSTELLATION_TYRANTRUM
# when :SHARPEDO; return VAR_CONSTELLATION_SHARPEDO
# when :ARCEUS; return VAR_CONSTELLATION_ARCEUS
end
end
def getNextLunarFeatherHint()
nb_feathers = pbGet(VAR_LUNAR_FEATHERS)
case nb_feathers
when 0
return "Find the first feather in the northernmost dwelling in the port of exquisite sunsets..."
when 1
return "Amidst a nursery for Pokémon youngsters, the second feather hides, surrounded by innocence."
when 2
return "Find the next one in the inn where water meets rest"
when 3
return "Find the next one inside the lone house in the city at the edge of civilization."
when 4
return "The final feather lies back in the refuge for orphaned Pokémon..."
else
return "Lie in the bed... Bring me the feathers..."
end
end
def apply_concert_lighting(light, duration = 1)
tone = Tone.new(0, 0, 0)
case light
when :GUITAR_HIT
tone = Tone.new(-50, -100, -50)
when :VERSE_1
tone = Tone.new(-90, -110, -50)
when :VERSE_2_LIGHT
tone = Tone.new(-40, -80, -30)
when :VERSE_2_DIM
tone = Tone.new(-60, -100, -50)
when :CHORUS_1
tone = Tone.new(0, -80, -50)
when :CHORUS_2
tone = Tone.new(0, -50, -80)
when :CHORUS_3
tone = Tone.new(0, -80, -80)
when :CHORUS_END
tone = Tone.new(-68, 0, -102)
when :MELOETTA_1
tone = Tone.new(-60, -50, 20)
end
$game_screen.start_tone_change(tone, duration)
end
def playMeloettaBandMusic()
unlocked_members = []
unlocked_members << :DRUM if $game_switches[SWITCH_BAND_DRUMMER]
unlocked_members << :AGUITAR if $game_switches[SWITCH_BAND_ACOUSTIC_GUITAR]
unlocked_members << :EGUITAR if $game_switches[SWITCH_BAND_ELECTRIC_GUITAR]
unlocked_members << :FLUTE if $game_switches[SWITCH_BAND_FLUTE]
unlocked_members << :HARP if $game_switches[SWITCH_BAND_HARP]
echoln unlocked_members
echoln (unlocked_members & [:DRUM, :AGUITAR, :EGUITAR, :FLUTE, :HARP])
track = "band/band_1"
if unlocked_members == [:DRUM, :AGUITAR, :EGUITAR, :FLUTE, :HARP]
track = "band/band_full"
else
if unlocked_members.include?(:FLUTE)
track = "band/band_5a"
elsif unlocked_members.include?(:HARP)
track = "band/band_5b"
else
if unlocked_members.include?(:EGUITAR) && unlocked_members.include?(:AGUITAR)
track = "band/band_4"
elsif unlocked_members.include?(:AGUITAR)
track = "band/band_3a"
elsif unlocked_members.include?(:EGUITAR)
track = "band/band_3b"
elsif unlocked_members.include?(:DRUM)
track = "band/band_2"
end
end
end
echoln track
pbBGMPlay(track)
end
def regirock_steel_move_boulder()
switches_position = [
[16, 21], [18, 21], [20, 21], [22, 21],
[16, 23], [22, 23],
[16, 25], [18, 25], [20, 25], [22, 25]
]
boulder_event = get_self
old_x = boulder_event.x
old_y = boulder_event.y
stepped_off_switch = switches_position.find { |position| position[0] == old_x && position[1] == old_y }
pbPushThisBoulder()
boulder_event = get_self
if stepped_off_switch
switch_event = $game_map.get_event_at_position(old_x, old_y, [boulder_event.id])
echoln switch_event.id if switch_event
pbSEPlay("Entering Door", nil, 80)
pbSetSelfSwitch(switch_event.id, "A", false) if switch_event
end
stepped_on_switch = switches_position.find { |position| position[0] == boulder_event.x && position[1] == boulder_event.y }
if stepped_on_switch
switch_event = $game_map.get_event_at_position(boulder_event.x, boulder_event.y, [boulder_event.id])
echoln switch_event.id if switch_event
pbSEPlay("Entering Door")
pbSetSelfSwitch(switch_event.id, "A", true) if switch_event
end
end
KANTO_DARKNESS_STAGE_1 = [
50, # Lavender town
409, # Route 8
351, # Route 9 (east)
495, # Route 9 (west)
154, # Route 10
108, # Saffron city
1, # Cerulean City
387, # Cerulean City (race)
106, # Route 4
8, # Route 24
9, # Route 25
400, # Pokemon Tower
401, # Pokemon Tower
402, # Pokemon Tower
403, # Pokemon Tower
467, # Pokemon Tower
468, # Pokemon Tower
469, # Pokemon Tower
159, # Route 12
349, # Rock tunnel
350, # Rock tunnel
512, # Rock tunnel (outdoor)
12, # Route 5
]
KANTO_DARKNESS_STAGE_2 = [
95, # Celadon city
436, # Celadon city dept store (roof)
143, # Route 23
167, # Crimson city
413, # Route 7
438, # Route 16
146, # Route 17
106, # Route 4
19, # Vermillion City
36, # S.S. Anne deck
16, # Route 6
437, # Route 13
155, # Route 11
140, # Diglett cave
398, # Diglett cave
399, # Diglett cave
]
KANTO_DARKNESS_STAGE_3 = [
472, # Fuchsia city
445, # Safari Zone 1
484, # Safari Zone 2
485, # Safari Zone 3
486, # Safari Zone 4
487, # Safari Zone 5
444, # Route 15
440, # Route 14
712, # Creepy house
517, # Route 18
57, # Route 19
227, # Route 19 (underwater)
56, # Route 19 (surf race)
58, # Route 20
480, # Route 20 underwater 1
228, # Route 20 underwater 2
98, # Cinnabar island
58, # Route 21
827, # Mt. Moon summit
]
KANTO_DARKNESS_STAGE_4 = KANTO_OUTDOOR_MAPS
def darknessEffectOnCurrentMap()
return if !$game_switches
return if !$game_switches[SWITCH_KANTO_DARKNESS]
return darknessEffectOnMap($game_map.map_id)
end
def darknessEffectOnMap(map_id)
return if !$game_switches
return if !$game_switches[SWITCH_KANTO_DARKNESS]
return if !KANTO_OUTDOOR_MAPS.include?(map_id)
dark_maps = []
dark_maps += KANTO_DARKNESS_STAGE_1 if $game_switches[SWITCH_KANTO_DARKNESS_STAGE_1]
dark_maps += KANTO_DARKNESS_STAGE_2 if $game_switches[SWITCH_KANTO_DARKNESS_STAGE_2]
dark_maps += KANTO_DARKNESS_STAGE_3 if $game_switches[SWITCH_KANTO_DARKNESS_STAGE_3]
dark_maps = KANTO_OUTDOOR_MAPS if $game_switches[SWITCH_KANTO_DARKNESS_STAGE_4]
return dark_maps.include?(map_id)
end
def apply_darkness()
$PokemonTemp.darknessSprite = DarknessSprite.new
darkness = $PokemonTemp.darknessSprite
darkness.radius = 276
while darkness.radius > 64
Graphics.update
Input.update
pbUpdateSceneMap
darkness.radius -= 4
end
$PokemonGlobal.flashUsed = false
$PokemonTemp.darknessSprite.dispose
Events.onMapSceneChange.trigger(self, $scene, true)
end
def isInMtMoon()
mt_moon_maps = [102, 103, 105, 496, 104]
return mt_moon_maps.include?($game_map.map_id)
end
def getMtMoonDirection()
maps_east = [380, # Pewter city
490, # Route 3
303, # indigo plateau
145, # Route 26
147, # Route 27
]
maps_south = [
8, # Route 24
9, # Route 25
143, # Route 23
167, # Crimson city
]
maps_west = [
106, # route 4
1, # cerulean
495, # route 9
351, # route 9
10 # cerulean cape
]
return 2 if maps_south.include?($game_map.map_id)
return 4 if maps_west.include?($game_map.map_id)
return 6 if maps_east.include?($game_map.map_id)
return 8 # north (most maps)
end
def Kernel.setRocketPassword(variableNum)
abilityIndex = rand(233)
speciesIndex = rand(PBSpecies.maxValue - 1)
word1 = PBSpecies.getName(speciesIndex)
word2 = GameData::Ability.get(abilityIndex).name
password = _INTL("{1}'s {2}", word1, word2)
pbSet(variableNum, password)
end
def obtainBadgeMessage(badgeName)
Kernel.pbMessage(_INTL("\\me[Badge get]{1} obtained the {2}!", $Trainer.name, badgeName))
end
def getFossilsGuyTeam(level)
base_poke_evolution_level = 20
fossils_evolution_level_1 = 30
fossils_evolution_level_2 = 50
fossils = []
base_poke = level <= base_poke_evolution_level ? :B88H109 : :B89H110
team = []
team << Pokemon.new(base_poke, level)
# Mt. Moon fossil
if $game_switches[SWITCH_PICKED_HELIC_FOSSIL]
fossils << :KABUTO if level < fossils_evolution_level_1
fossils << :KABUTOPS if level >= fossils_evolution_level_1
elsif $game_switches[SWITCH_PICKED_DOME_FOSSIL]
fossils << :OMANYTE if level < fossils_evolution_level_1
fossils << :OMASTAR if level >= fossils_evolution_level_1
end
# S.S. Anne fossil
if $game_switches[SWITCH_PICKED_LILEEP_FOSSIL]
fossils << :ANORITH if level < fossils_evolution_level_1
fossils << :ARMALDO if level >= fossils_evolution_level_1
elsif $game_switches[SWITCH_PICKED_ANORITH_FOSSIL]
fossils << :LILEEP if level < fossils_evolution_level_1
fossils << :CRADILY if level >= fossils_evolution_level_1
end
# Celadon fossil
if $game_switches[SWITCH_PICKED_ARMOR_FOSSIL]
fossils << :CRANIDOS if level < fossils_evolution_level_2
fossils << :RAMPARDOS if level >= fossils_evolution_level_2
elsif $game_switches[SWITCH_PICKED_SKULL_FOSSIL]
fossils << :SHIELDON if level < fossils_evolution_level_2
fossils << :BASTIODON if level >= fossils_evolution_level_2
end
skip_next = false
for index in 0..fossils.length
if index == fossils.length - 1
team << Pokemon.new(fossils[index], level)
else
if skip_next
skip_next = false
next
end
head_poke = fossils[index]
body_poke = fossils[index + 1]
if head_poke && body_poke
newPoke = getFusionSpecies(dexNum(body_poke), dexNum(head_poke))
team << Pokemon.new(newPoke, level)
skip_next = true
end
end
end
return team
end
# tradedPoke = pbGet(154)
# party=[tradedPoke]
# customTrainerBattle("Eusine",
# :MYSTICALMAN,
# party,
# tradedPoke.level,
# "Okay, okay I'll give it back!" )
def fossilsGuyBattle(level = 20, end_message = "")
team = getFossilsGuyTeam(level)
customTrainerBattle("Miguel",
:SUPERNERD,
team,
level,
end_message
)
end

View File

@@ -0,0 +1,49 @@
# frozen_string_literal: true
def addWaterCausticsEffect(fog_name = "caustic1", opacity = 16)
$game_map.fog_name = fog_name
$game_map.fog_hue = 0
$game_map.fog_opacity = opacity
#$game_map.fog_blend_type = @parameters[4]
$game_map.fog_zoom = 200
$game_map.fog_sx = 2
$game_map.fog_sy = 2
$game_map.setFog2(fog_name, -3, 0, opacity,)
end
def stopWaterCausticsEffect()
$game_map.fog_opacity = 0
$game_map.eraseFog2()
end
def clear_all_images()
for i in 1..99
# echoln i.to_s + " : " + $game_screen.pictures[i].name
$game_screen.pictures[i].erase
end
end
def playPokeFluteAnimation
# return if $Trainer.outfit != 0
# $game_player.setDefaultCharName("players/pokeflute", 0, false)
# Graphics.update
# Input.update
# pbUpdateSceneMap
end
def restoreDefaultCharacterSprite(charset_number = 0)
meta = GameData::Metadata.get_player($Trainer.character_ID)
$game_player.setDefaultCharName(nil, 0, false)
$game_player.character_name = meta[1]
Graphics.update
Input.update
pbUpdateSceneMap
end
# if need to play animation from event route
def playAnimation(animationId, x, y)
return if !$scene.is_a?(Scene_Map)
$scene.spriteset.addUserAnimation(animationId, x, y, true)
end

View File

@@ -0,0 +1,167 @@
def optionsMenu(options = [], cmdIfCancel = -1, startingOption = 0)
cmdIfCancel = -1 if !cmdIfCancel
result = pbShowCommands(nil, options, cmdIfCancel, startingOption)
echoln "menuResult :#{result}"
return result
end
def displaySpriteWindowWithMessage(pif_sprite, message = "", x = 0, y = 0, z = 0)
spriteLoader = BattleSpriteLoader.new
sprite_bitmap = spriteLoader.load_pif_sprite_directly(pif_sprite)
pictureWindow = PictureWindow.new(sprite_bitmap.bitmap)
pictureWindow.opacity = 0
pictureWindow.z = z
pictureWindow.x = x
pictureWindow.y = y
pbMessage(message)
pictureWindow.dispose
end
def select_any_pokemon()
commands = []
for dex_num in 1..NB_POKEMON
species = getPokemon(dex_num)
commands.push([dex_num - 1, species.real_name, species.id])
end
return pbChooseList(commands, 0, nil, 1)
end
def purchaseDyeKitMenu(hats_kit_price=0,clothes_kit_price=0)
commands = []
command_hats = "Hats Dye Kit ($#{hats_kit_price})"
command_clothes = "Clothes Dye Kit ($#{clothes_kit_price})"
command_cancel = "Cancel"
commands << command_hats if !$PokemonBag.pbHasItem?(:HATSDYEKIT)
commands << command_clothes if !$PokemonBag.pbHasItem?(:CLOTHESDYEKIT)
commands << command_cancel
if commands.length <= 1
pbCallBub(2,@event_id)
pbMessage("\\C[1]Dye Kits\\C[0] can be used to dye clothes all sorts of colours!")
pbCallBub(2,@event_id)
pbMessage("You can use them at any time when you change clothes.")
return
end
pbCallBub(2,@event_id)
pbMessage("\\GWelcome! Are you interested in dyeing your outfits different colours?")
pbCallBub(2,@event_id)
pbMessage("I make handy \\C[1]Dye Kits\\C[0] from my Smeargle's paint that can be used to dye your outfits any color you want!")
pbCallBub(2,@event_id)
pbMessage("\\GWhat's more is that it's reusable so you can go completely wild with it if you want! Are you interested?")
choice = optionsMenu(commands,commands.length)
case commands[choice]
when command_hats
if $Trainer.money < hats_kit_price
pbCallBub(2,@event_id)
pbMessage("Oh, you don't have enough money...")
return
end
pbMessage("\\G\\PN purchased the dye kit.")
$Trainer.money -= hats_kit_price
pbSEPlay("SlotsCoin")
Kernel.pbReceiveItem(:HATSDYEKIT)
pbCallBub(2,@event_id)
pbMessage("\\GHere you go! Have fun dyeing your hats!")
when command_clothes
if $Trainer.money < clothes_kit_price
pbCallBub(2,@event_id)
pbMessage("Oh, you don't have enough money...")
return
end
pbMessage("\\G\\PN purchased the dye kit.")
$Trainer.money -= clothes_kit_price
pbSEPlay("SlotsCoin")
Kernel.pbReceiveItem(:CLOTHESDYEKIT)
pbCallBub(2,@event_id)
pbMessage("\\GHere you go! Have fun dyeing your clothes!")
end
pbCallBub(2,@event_id)
pbMessage("You can use \\C[1]Dye Kits\\C[0] at any time when you change clothes.")
end
def promptCaughtPokemonAction(pokemon)
pickedOption = false
return pbStorePokemon(pokemon) if !$Trainer.party_full?
return promptKeepOrRelease(pokemon) if isOnPinkanIsland() && !$game_switches[SWITCH_PINKAN_FINISHED]
while !pickedOption
command = pbMessage(_INTL("\\ts[]Your team is full!"),
[_INTL("Add to your party"), _INTL("Store to PC"),], 2)
echoln ("command " + command.to_s)
case command
when 0 # SWAP
if swapCaughtPokemon(pokemon)
echoln pickedOption
pickedOption = true
end
else
# STORE
pbStorePokemon(pokemon)
echoln pickedOption
pickedOption = true
end
end
end
def promptKeepOrRelease(pokemon)
pickedOption = false
while !pickedOption
command = pbMessage(_INTL("\\ts[]Your team is full!"),
[_INTL("Release a party member"), _INTL("Release this #{pokemon.name}"),], 2)
echoln ("command " + command.to_s)
case command
when 0 # SWAP
if swapReleaseCaughtPokemon(pokemon)
pickedOption = true
end
else
pickedOption = true
end
end
end
# def pbChoosePokemon(variableNumber, nameVarNumber, ableProc = nil, allowIneligible = false)
def swapCaughtPokemon(caughtPokemon)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
!(poke.isShadow? rescue false)
})
index = pbGet(1)
return false if index == -1
$PokemonStorage.pbStoreCaught($Trainer.party[index])
pbRemovePokemonAt(index)
pbStorePokemon(caughtPokemon)
tmp = $Trainer.party[index]
$Trainer.party[index] = $Trainer.party[-1]
$Trainer.party[-1] = tmp
return true
end
def swapReleaseCaughtPokemon(caughtPokemon)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
!(poke.isShadow? rescue false)
})
index = pbGet(1)
return false if index == -1
releasedPokemon = $Trainer.party[index]
pbMessage("#{releasedPokemon.name} was released.")
pbRemovePokemonAt(index)
pbStorePokemon(caughtPokemon)
tmp = $Trainer.party[index]
$Trainer.party[index] = $Trainer.party[-1]
$Trainer.party[-1] = tmp
return true
end

View File

@@ -0,0 +1,56 @@
# frozen_string_literal: true
def unlock_easter_egg_hats()
if $Trainer.name == "Ash"
$Trainer.hat = HAT_ASH
$Trainer.unlock_hat(HAT_ASH)
end
if $Trainer.name == "Frogman"
$Trainer.hat = HAT_FROG
$Trainer.unlock_hat(HAT_FROG)
end
end
def setupStartingOutfit()
$Trainer.hat = nil
$Trainer.clothes = STARTING_OUTFIT
unlock_easter_egg_hats()
gender = pbGet(VAR_TRAINER_GENDER)
if gender == GENDER_FEMALE
$Trainer.unlock_clothes(DEFAULT_OUTFIT_FEMALE, true)
$Trainer.unlock_hat(DEFAULT_OUTFIT_FEMALE, true)
$Trainer.hair = "3_" + DEFAULT_OUTFIT_FEMALE if !$Trainer.hair # when migrating old savefiles
elsif gender == GENDER_MALE
$Trainer.unlock_clothes(DEFAULT_OUTFIT_MALE, true)
$Trainer.unlock_hat(DEFAULT_OUTFIT_MALE, true)
echoln $Trainer.hair
$Trainer.hair = ("3_" + DEFAULT_OUTFIT_MALE) if !$Trainer.hair # when migrating old savefiles
echoln $Trainer.hair
end
$Trainer.unlock_hair(DEFAULT_OUTFIT_MALE, true)
$Trainer.unlock_hair(DEFAULT_OUTFIT_FEMALE, true)
$Trainer.unlock_clothes(STARTING_OUTFIT, true)
end
def give_date_specific_hats()
current_date = Time.new
# Christmas
if (current_date.day == 24 || current_date.day == 25) && current_date.month == 12
if !$Trainer.unlocked_hats.include?(HAT_SANTA)
pbCallBub(2, @event_id, true)
pbMessage("Hi! We're giving out a special hat today for the holidays season. Enjoy!")
obtainHat(HAT_SANTA)
end
end
# April's fool
if (current_date.day == 1 && current_date.month == 4)
if !$Trainer.unlocked_hats.include?(HAT_CLOWN)
pbCallBub(2, @event_id, true)
pbMessage("Hi! We're giving out this fun accessory for this special day. Enjoy!")
obtainHat(HAT_CLOWN)
end
end
end

View File

@@ -0,0 +1,8 @@
def isPlayerMale()
return pbGet(VAR_TRAINER_GENDER) == GENDER_MALE
end
def isPlayerFemale()
return pbGet(VAR_TRAINER_GENDER) == GENDER_FEMALE
end# frozen_string_literal: true

View File

@@ -0,0 +1,247 @@
def replaceFusionSpecies(pokemon, speciesToChange, newSpecies)
currentBody = pokemon.species_data.get_body_species_symbol()
currentHead = pokemon.species_data.get_head_species_symbol()
should_update_body = currentBody == speciesToChange
should_update_head = currentHead == speciesToChange
echoln speciesToChange
echoln currentBody
echoln currentHead
return if !should_update_body && !should_update_head
newSpeciesBody = should_update_body ? newSpecies : currentBody
newSpeciesHead = should_update_head ? newSpecies : currentHead
newSpecies = getFusionSpecies(newSpeciesBody, newSpeciesHead)
echoln newSpecies.id_number
pokemon.species = newSpecies
end
def changeSpeciesSpecific(pokemon, newSpecies)
pokemon.species = newSpecies
$Trainer.pokedex.set_seen(newSpecies)
$Trainer.pokedex.set_owned(newSpecies)
end
def setPokemonMoves(pokemon, move_ids = [])
moves = []
move_ids.each { |move_id|
moves << Pokemon::Move.new(move_id)
}
pokemon.moves = moves
end
def getGenericPokemonCryText(pokemonSpecies)
case pokemonSpecies
when 25
return "Pika!"
when 16, 17, 18, 21, 22, 144, 145, 146, 227, 417, 418, 372 # birds
return "Squawk!"
when 163, 164
return "Hoot!" # owl
else
return "Guaugh!"
end
end
def Kernel.getPlateType(item)
return :FIGHTING if item == PBItems::FISTPLATE
return :FLYING if item == PBItems::SKYPLATE
return :POISON if item == PBItems::TOXICPLATE
return :GROUND if item == PBItems::EARTHPLATE
return :ROCK if item == PBItems::STONEPLATE
return :BUG if item == PBItems::INSECTPLATE
return :GHOST if item == PBItems::SPOOKYPLATE
return :STEEL if item == PBItems::IRONPLATE
return :FIRE if item == PBItems::FLAMEPLATE
return :WATER if item == PBItems::SPLASHPLATE
return :GRASS if item == PBItems::MEADOWPLATE
return :ELECTRIC if item == PBItems::ZAPPLATE
return :PSYCHIC if item == PBItems::MINDPLATE
return :ICE if item == PBItems::ICICLEPLATE
return :DRAGON if item == PBItems::DRACOPLATE
return :DARK if item == PBItems::DREADPLATE
return :FAIRY if item == PBItems::PIXIEPLATE
return -1
end
def Kernel.listPlatesInBag()
list = []
list << PBItems::FISTPLATE if $PokemonBag.pbQuantity(:FISTPLATE) >= 1
list << PBItems::SKYPLATE if $PokemonBag.pbQuantity(:SKYPLATE) >= 1
list << PBItems::TOXICPLATE if $PokemonBag.pbQuantity(:TOXICPLATE) >= 1
list << PBItems::EARTHPLATE if $PokemonBag.pbQuantity(:EARTHPLATE) >= 1
list << PBItems::STONEPLATE if $PokemonBag.pbQuantity(:STONEPLATE) >= 1
list << PBItems::INSECTPLATE if $PokemonBag.pbQuantity(:INSECTPLATE) >= 1
list << PBItems::SPOOKYPLATE if $PokemonBag.pbQuantity(:SPOOKYPLATE) >= 1
list << PBItems::IRONPLATE if $PokemonBag.pbQuantity(:IRONPLATE) >= 1
list << PBItems::FLAMEPLATE if $PokemonBag.pbQuantity(:FLAMEPLATE) >= 1
list << PBItems::SPLASHPLATE if $PokemonBag.pbQuantity(:SPLASHPLATE) >= 1
list << PBItems::MEADOWPLATE if $PokemonBag.pbQuantity(:MEADOWPLATE) >= 1
list << PBItems::ZAPPLATE if $PokemonBag.pbQuantity(:ZAPPLATE) >= 1
list << PBItems::MINDPLATE if $PokemonBag.pbQuantity(:MINDPLATE) >= 1
list << PBItems::ICICLEPLATE if $PokemonBag.pbQuantity(:ICICLEPLATE) >= 1
list << PBItems::DRACOPLATE if $PokemonBag.pbQuantity(:DRACOPLATE) >= 1
list << PBItems::DREADPLATE if $PokemonBag.pbQuantity(:DREADPLATE) >= 1
list << PBItems::PIXIEPLATE if $PokemonBag.pbQuantity(:PIXIEPLATE) >= 1
return list
end
def getArceusPlateType(heldItem)
return :NORMAL if heldItem == nil
case heldItem
when :FISTPLATE
return :FIGHTING
when :SKYPLATE
return :FLYING
when :TOXICPLATE
return :POISON
when :EARTHPLATE
return :GROUND
when :STONEPLATE
return :ROCK
when :INSECTPLATE
return :BUG
when :SPOOKYPLATE
return :GHOST
when :IRONPLATE
return :STEEL
when :FLAMEPLATE
return :FIRE
when :SPLASHPLATE
return :WATER
when :MEADOWPLATE
return :GRASS
when :ZAPPLATE
return :ELECTRIC
when :MINDPLATE
return :PSYCHIC
when :ICICLEPLATE
return :ICE
when :DRACOPLATE
return :DRAGON
when :DREADPLATE
return :DARK
when :PIXIEPLATE
return :FAIRY
else
return :NORMAL
end
end
def changeOricorioForm(pokemon, form = nil)
oricorio_forms = [:ORICORIO_1, :ORICORIO_2, :ORICORIO_3, :ORICORIO_4]
body_id = pokemon.isFusion? ? get_body_species_from_symbol(pokemon.species) : pokemon.species
head_id = pokemon.isFusion? ? get_head_species_from_symbol(pokemon.species) : pokemon.species
oricorio_body = oricorio_forms.include?(body_id)
oricorio_head = oricorio_forms.include?(head_id)
if form == 1
body_id = :ORICORIO_1 if oricorio_body
head_id = :ORICORIO_1 if oricorio_head
elsif form == 2
body_id = :ORICORIO_2 if oricorio_body
head_id = :ORICORIO_2 if oricorio_head
elsif form == 3
body_id = :ORICORIO_3 if oricorio_body
head_id = :ORICORIO_3 if oricorio_head
elsif form == 4
body_id = :ORICORIO_4 if oricorio_body
head_id = :ORICORIO_4 if oricorio_head
else
return false
end
head_number = getDexNumberForSpecies(head_id)
body_number = getDexNumberForSpecies(body_id)
newForm = pokemon.isFusion? ? getSpeciesIdForFusion(head_number, body_number) : head_id
$Trainer.pokedex.set_seen(newForm)
$Trainer.pokedex.set_owned(newForm)
pokemon.species = newForm
return true
end
def changeOricorioFlower(form = 1)
if $PokemonGlobal.stepcount % 25 == 0
if !hatUnlocked?(HAT_FLOWER) && rand(2) == 0
obtainHat(HAT_FLOWER)
$PokemonGlobal.stepcount += 1
else
pbMessage(_INTL("Woah! A Pokémon jumped out of the flower!"))
pbWildBattle(:FOMANTIS, 10)
$PokemonGlobal.stepcount += 1
end
end
return if !($Trainer.has_species_or_fusion?(:ORICORIO_1) || $Trainer.has_species_or_fusion?(:ORICORIO_2) || $Trainer.has_species_or_fusion?(:ORICORIO_3) || $Trainer.has_species_or_fusion?(:ORICORIO_4))
message = ""
form_name = ""
if form == 1
message = "It's a flower with red nectar. "
form_name = "Baile"
elsif form == 2
message = "It's a flower with yellow nectar. "
form_name = "Pom-pom"
elsif form == 3
message = "It's a flower with pink nectar. "
form_name = "Pa'u"
elsif form == 4
message = "It's a flower with blue nectar. "
form_name = "Sensu"
end
message = message + "Show it to a Pokémon?"
if pbConfirmMessage(message)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
(Kernel.isPartPokemon(poke, :ORICORIO_1) ||
Kernel.isPartPokemon(poke, :ORICORIO_2) ||
Kernel.isPartPokemon(poke, :ORICORIO_3) ||
Kernel.isPartPokemon(poke, :ORICORIO_4))
})
if (pbGet(1) != -1)
poke = $Trainer.party[pbGet(1)]
if changeOricorioForm(poke, form)
pbMessage(_INTL("{1} switched to the {2} style", poke.name, form_name))
pbSet(1, poke.name)
else
pbMessage(_INTL("{1} remained the same...", poke.name, form_name))
end
end
end
end
def oricorioEventPickFlower(flower_color)
quest_progression = pbGet(VAR_ORICORIO_FLOWERS)
if flower_color == :PINK
if !$game_switches[SWITCH_ORICORIO_QUEST_PINK]
pbMessage(_INTL("Woah! A Pokémon jumped out of the flower!"))
pbWildBattle(:FOMANTIS, 10)
end
$game_switches[SWITCH_ORICORIO_QUEST_PINK] = true
pbMessage(_INTL("It's a flower with pink nectar."))
pbSEPlay("MiningAllFound")
pbMessage(_INTL("{1} picked some of the pink flowers.", $Trainer.name))
elsif flower_color == :RED && quest_progression == 1
$game_switches[SWITCH_ORICORIO_QUEST_RED] = true
pbMessage(_INTL("It's a flower with red nectar."))
pbSEPlay("MiningAllFound")
pbMessage(_INTL("{1} picked some of the red flowers.", $Trainer.name))
elsif flower_color == :BLUE && quest_progression == 2
$game_switches[SWITCH_ORICORIO_QUEST_BLUE] = true
pbMessage(_INTL("It's a flower with blue nectar."))
pbSEPlay("MiningAllFound")
pbMessage(_INTL("{1} picked some of the blue flowers.", $Trainer.name))
end
end

View File

@@ -0,0 +1,102 @@
def fixMissedHMs()
# Flash
if $PokemonBag.pbQuantity(:HM08) < 1 && $PokemonGlobal.questRewardsObtained.include?(:HM08)
pbReceiveItem(:HM08)
end
# Cut
if $PokemonBag.pbQuantity(:HM01) < 1 && $game_switches[SWITCH_SS_ANNE_DEPARTED]
pbReceiveItem(:HM01)
end
# Strength
if $PokemonBag.pbQuantity(:HM04) < 1 && $game_switches[SWITCH_SNORLAX_GONE_ROUTE_12]
pbReceiveItem(:HM04)
end
# Surf
if $PokemonBag.pbQuantity(:HM03) < 1 && $game_self_switches[[107, 1, "A"]]
pbReceiveItem(:HM03)
end
# Teleport
if $PokemonBag.pbQuantity(:HM07) < 1 && $game_switches[SWITCH_TELEPORT_NPC]
pbReceiveItem(:HM07)
end
# Fly
if $PokemonBag.pbQuantity(:HM02) < 1 && $game_self_switches[[439, 1, "B"]]
pbReceiveItem(:HM02)
end
# Waterfall
if $PokemonBag.pbQuantity(:HM05) < 1 && $game_switches[SWITCH_GOT_WATERFALL]
pbReceiveItem(:HM05)
end
# Dive
if $PokemonBag.pbQuantity(:HM06) < 1 && $game_switches[SWITCH_GOT_DIVE]
pbReceiveItem(:HM06)
end
# Rock Climb
if $PokemonBag.pbQuantity(:HM10) < 1 && $game_switches[SWITCH_GOT_ROCK_CLIMB]
pbReceiveItem(:HM10)
end
end
def fixFinishedRocketQuests()
fix_broken_TR_quests()
var_tr_missions_cerulean = 288
switch_tr_mission_cerulean_4 = 1116
switch_tr_mission_celadon_1 = 1084
switch_tr_mission_celadon_2 = 1086
switch_tr_mission_celadon_3 = 1088
switch_tr_mission_celadon_4 = 1110
switch_pinkan_done = 1119
nb_cerulean_missions = pbGet(var_tr_missions_cerulean)
finishTRQuest("tr_cerulean_1", :SUCCESS, true) if nb_cerulean_missions >= 1 && !pbCompletedQuest?("tr_cerulean_1")
echoln pbCompletedQuest?("tr_cerulean_1")
finishTRQuest("tr_cerulean_2", :SUCCESS, true) if nb_cerulean_missions >= 2 && !pbCompletedQuest?("tr_cerulean_2")
finishTRQuest("tr_cerulean_3", :SUCCESS, true) if nb_cerulean_missions >= 3 && !pbCompletedQuest?("tr_cerulean_3")
finishTRQuest("tr_cerulean_4", :SUCCESS, true) if $game_switches[switch_tr_mission_cerulean_4] && !pbCompletedQuest?("tr_cerulean_4")
finishTRQuest("tr_celadon_1", :SUCCESS, true) if $game_switches[switch_tr_mission_celadon_1] && !pbCompletedQuest?("tr_celadon_1")
finishTRQuest("tr_celadon_2", :SUCCESS, true) if $game_switches[switch_tr_mission_celadon_2] && !pbCompletedQuest?("tr_celadon_2")
finishTRQuest("tr_celadon_3", :SUCCESS, true) if $game_switches[switch_tr_mission_celadon_3] && !pbCompletedQuest?("tr_celadon_3")
finishTRQuest("tr_celadon_4", :SUCCESS, true) if $game_switches[switch_tr_mission_celadon_4] && !pbCompletedQuest?("tr_celadon_4")
finishTRQuest("tr_pinkan", :SUCCESS, true) if $game_switches[switch_pinkan_done] && !pbCompletedQuest?("tr_pinkan")
end
def fix_broken_TR_quests()
for trainer_quest in $Trainer.quests
if trainer_quest.id == 0 # tr quests were all set to ID 0 instead of their real ID in v 6.4.0
for rocket_quest_id in TR_QUESTS.keys
rocket_quest = TR_QUESTS[rocket_quest_id]
next if !rocket_quest
if trainer_quest.name == rocket_quest.name
trainer_quest.id = rocket_quest_id
end
end
end
end
end
def failAllIncompleteRocketQuests()
for trainer_quest in $Trainer.quests
finishTRQuest("tr_cerulean_1", :FAILURE) if trainer_quest.id == "tr_cerulean_1" && !pbCompletedQuest?("tr_cerulean_1")
finishTRQuest("tr_cerulean_2", :FAILURE) if trainer_quest.id == "tr_cerulean_2" && !pbCompletedQuest?("tr_cerulean_2")
finishTRQuest("tr_cerulean_3", :FAILURE) if trainer_quest.id == "tr_cerulean_3" && !pbCompletedQuest?("tr_cerulean_3")
finishTRQuest("tr_cerulean_4", :FAILURE) if trainer_quest.id == "tr_cerulean_4" && !pbCompletedQuest?("tr_cerulean_4")
finishTRQuest("tr_celadon_1", :FAILURE) if trainer_quest.id == "tr_celadon_1" && !pbCompletedQuest?("tr_celadon_1")
finishTRQuest("tr_celadon_2", :FAILURE) if trainer_quest.id == "tr_celadon_2" && !pbCompletedQuest?("tr_celadon_2")
finishTRQuest("tr_celadon_3", :FAILURE) if trainer_quest.id == "tr_celadon_3" && !pbCompletedQuest?("tr_celadon_3")
finishTRQuest("tr_celadon_4", :FAILURE) if trainer_quest.id == "tr_celadon_4" && !pbCompletedQuest?("tr_celadon_4")
end
end

View File

@@ -0,0 +1,7 @@
#ex:Game_Event.new
# forced_sprites = {"1.133" => "a"}
# setForcedAltSprites(forced_sprites)
#
def setForcedAltSprites(forcedSprites_map)
$PokemonTemp.forced_alt_sprites = forcedSprites_map
end

View File

@@ -0,0 +1,145 @@
# frozen_string_literal: true
# todo: implement
def getMappedKeyFor(internalKey)
keybinding_fileName = "keybindings.mkxp1"
path = System.data_directory + keybinding_fileName
parse_keybindings(path)
# echoln Keybindings.new(path).bindings
end
def formatNumberToString(number)
return number.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
end
def playCry(pokemonSpeciesSymbol)
species = GameData::Species.get(pokemonSpeciesSymbol).species
GameData::Species.play_cry_from_species(species)
end
# Get difficulty for displaying in-game
def getDisplayDifficulty
if $game_switches[SWITCH_GAME_DIFFICULTY_EASY] || $Trainer.lowest_difficulty <= 0
return getDisplayDifficultyFromIndex(0)
elsif $Trainer.lowest_difficulty <= 1
return getDisplayDifficultyFromIndex(1)
elsif $game_switches[SWITCH_GAME_DIFFICULTY_HARD]
return getDisplayDifficultyFromIndex(2)
else
return getDisplayDifficultyFromIndex(1)
end
end
def getDisplayDifficultyFromIndex(difficultyIndex)
return "Easy" if difficultyIndex == 0
return "Normal" if difficultyIndex == 1
return "Hard" if difficultyIndex == 2
return "???"
end
def getGameModeFromIndex(index)
return "Classic" if index == 0
return "Random" if index == 1
return "Remix" if index == 2
return "Expert" if index == 3
return "Species" if index == 4
return "Debug" if index == 5
return ""
end
def openUrlInBrowser(url = "")
begin
# Open the URL in the default web browser
system("xdg-open", url) || system("open", url) || system("start", url)
rescue
Input.clipboard = url
pbMessage("The game could not open the link in the browser")
pbMessage("The link has been copied to your clipboard instead")
end
end
def clearAllSelfSwitches(mapID, switch = "A", newValue = false)
map = $MapFactory.getMap(mapID, false)
map.events.each { |event_array|
event_id = event_array[0]
pbSetSelfSwitch(event_id, switch, newValue, mapID)
}
end
def isTuesdayNight()
day = getDayOfTheWeek()
hour = pbGetTimeNow().hour
echoln hour
return (day == :TUESDAY && hour >= 20) || (day == :WEDNESDAY && hour < 5)
end
def setDifficulty(index)
$Trainer.selected_difficulty = index
case index
when 0 # EASY
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = true
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = false
when 1 # NORMAL
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = false
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = false
when 2 # HARD
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = false
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = true
end
end
# Old menu for changing difficulty - unused
def change_game_difficulty(down_only = false)
message = "The game is currently on " + get_difficulty_text() + " difficulty."
pbMessage(message)
choice_easy = "Easy"
choice_normal = "Normal"
choice_hard = "Hard"
choice_cancel = "Cancel"
available_difficulties = []
currentDifficulty = get_current_game_difficulty
if down_only
if currentDifficulty == :HARD
available_difficulties << choice_hard
available_difficulties << choice_normal
available_difficulties << choice_easy
elsif currentDifficulty == :NORMAL
available_difficulties << choice_normal
available_difficulties << choice_easy
elsif currentDifficulty == :EASY
available_difficulties << choice_easy
end
else
available_difficulties << choice_easy
available_difficulties << choice_normal
available_difficulties << choice_hard
end
available_difficulties << choice_cancel
index = pbMessage("Select a new difficulty", available_difficulties, available_difficulties[-1])
choice = available_difficulties[index]
case choice
when choice_easy
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = true
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = false
when choice_normal
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = false
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = false
when choice_hard
$game_switches[SWITCH_GAME_DIFFICULTY_EASY] = false
$game_switches[SWITCH_GAME_DIFFICULTY_HARD] = true
when choice_cancel
return
end
message = "The game is currently on " + get_difficulty_text() + " difficulty."
pbMessage(message)
end

View File

@@ -0,0 +1,34 @@
SWITCH_GYM_RANDOM_EACH_BATTLE=668
SWITCH_NO_BUMP_SOUND=108
SWITCH_HAS_PREVIOUS_SAVEFILE = 972
VARIABLE_BATTLE_STYLE = 199
def setup_new_game()
set_new_game_switches
set_new_game_variables
setup_player
setup_randomizer
end
def set_new_game_switches
$game_switches[SWITCH_GYM_RANDOM_EACH_BATTLE] = true
$game_switches[SWITCH_NO_BUMP_SOUND] = true
$game_switches[SWITCH_HAS_PREVIOUS_SAVEFILE]= SaveData.exists?
end
def set_new_game_variables
pbSet(VARIABLE_BATTLE_STYLE,0)
end
def setup_player
$player.has_running_shoes=true
#pbChangePlayer(0)
end
def setup_randomizer
#init the random items hash even if it's not used
#pbShuffleItems
#pbShuffleTMs
end

View File

@@ -0,0 +1,672 @@
# frozen_string_literal: true
#==============================================================================#
# Pokémon Essentials #
# Version 19.1.dev #
# https://github.com/Maruno17/pokemon-essentials #
#==============================================================================#
module Settings
# The version of your game. It has to adhere to the MAJOR.MINOR.PATCH format.
GAME_VERSION = '6.5.1'
GAME_VERSION_NUMBER = "6.5.1"
LATEST_GAME_RELEASE = "6.5"
POKERADAR_LIGHT_ANIMATION_RED_ID = 17
POKERADAR_LIGHT_ANIMATION_GREEN_ID = 18
POKERADAR_HIDDEN_ABILITY_POKE_CHANCE = 32
POKERADAR_BATTERY_STEPS = 0
LEADER_VICTORY_MUSIC="Battle victory leader"
TRAINER_VICTORY_MUSIC="trainer-victory"
WILD_VICTORY_MUSIC="wild-victory"
#getRandomCustomFusionForIntro
FUSION_ICON_SPRITE_OFFSET = 10
#Infinite fusion settings
NB_POKEMON = 501
CUSTOM_BASE_SPRITES_FOLDER = "Graphics/CustomBattlers/local_sprites/BaseSprites/"
CUSTOM_BATTLERS_FOLDER = "Graphics/CustomBattlers/"
CUSTOM_SPRITES_TO_IMPORT_FOLDER = "Graphics/CustomBattlers/Sprites to import/"
CUSTOM_BATTLERS_FOLDER_INDEXED = "Graphics/CustomBattlers/local_sprites/indexed/"
CUSTOM_BASE_SPRITE_FOLDER = "Graphics/CustomBattlers/local_sprites/BaseSprites/"
BATTLERS_FOLDER = "Graphics/Battlers/Autogens/"
DOWNLOADED_SPRITES_FOLDER = "Graphics/temp/"
DEFAULT_SPRITE_PATH = "Graphics/Battlers/Special/000.png"
CREDITS_FILE_PATH = "Data/sprites/Sprite Credits.csv"
VERSION_FILE_PATH = "Data/VERSION"
CUSTOM_SPRITES_FILE_PATH = "Data/sprites/CUSTOM_SPRITES"
BASE_SPRITES_FILE_PATH = "Data/sprites/BASE_SPRITES"
CUSTOM_DEX_ENTRIES_PATH = "Data/pokedex/dex.json"
AI_DEX_ENTRIES_PATH = "Data/pokedex/generated_entries.json"
POKEDEX_ENTRIES_PATH = "Data/pokedex/all_entries.json"
UPDATED_SPRITESHEETS_CACHE = "Data/sprites/updated_spritesheets_cache"
BACK_ITEM_ICON_PATH = "Graphics/Items/back.png"
PLAYER_GRAPHICS_FOLDER = "Graphics/Characters/player/"
PLAYER_HAT_FOLDER = 'hat'
PLAYER_HAIR_FOLDER = 'hair'
PLAYER_CLOTHES_FOLDER = 'clothes'
PLAYER_BALL_FOLDER = 'balls'
PLAYER_TEMP_OUTFIT_FALLBACK = 'temp'
HATS_DATA_PATH = "Data/outfits/hats_data.json"
HAIRSTYLE_DATA_PATH = "Data/outfits/hairstyles_data.json"
CLOTHES_DATA_PATH = "Data/outfits/clothes_data.json"
PLAYER_SURFBASE_FOLDER = 'surf_base/'
OW_SHINE_ANIMATION_ID=25
HTTP_CONFIGS_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/pif-downloadables/refs/heads/master/Settings.rb"
HTTP_CONFIGS_FILE_PATH = "Data/Scripts/DownloadedSettings.rb"
SPRITES_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/infinitefusion-e18/main/Data/sprites/CUSTOM_SPRITES"
BASE_SPRITES_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/infinitefusion-e18/main/Data/sprites/BASE_SPRITES"
CREDITS_FILE_URL = "https://infinitefusion.net/Sprite Credits.csv"
CUSTOM_DEX_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/pif-downloadables/refs/heads/master/dex.json"
STARTUP_MESSAGES = ""
LEVEL_CAPS=[12,22,26,35,38,45,51,54,62,62,63,64,64,65,67,68]
CUSTOM_ENTRIES_NAME_PLACEHOLDER = "POKENAME"
DEFAULT_SPEED_UP_SPEED=2
FRONTSPRITE_POSITION_OFFSET = 20
FRONTSPRITE_SCALE = 0.6666666666666666
BACKRPSPRITE_SCALE = 1
EGGSPRITE_SCALE = 1
BACKSPRITE_POSITION_OFFSET = 20
FRONTSPRITE_POSITION = 200
SHINY_HUE_OFFSET = 75
NO_LEVEL_MODE_LEVEL_INCR = 5.8
NO_LEVEL_MODE_LEVEL_BASE = 6
SAVEFILE_NB_BACKUPS=10
DISCORD_URL = "https://discord.com/invite/infinitefusion"
WIKI_URL = "https://infinitefusion.fandom.com/"
AI_ENTRIES_URL = "https://ai-entries.pkmninfinitefusion.workers.dev/"
AI_ENTRIES_RATE_MAX_NB_REQUESTS = 10 #Nb. requests allowed in each time window
AI_ENTRIES_RATE_TIME_WINDOW = 120 # In seconds
AI_ENTRIES_RATE_LOG_FILE = 'Data/pokedex/dex_rate_limit.log' # Path to the log file
CUSTOMSPRITES_RATE_MAX_NB_REQUESTS = 15 #Nb. requests allowed in each time window
CUSTOMSPRITES_ENTRIES_RATE_TIME_WINDOW = 120 # In seconds
CUSTOMSPRITES_RATE_LOG_FILE = 'Data/sprites/sprites_rate_limit.log' # Path to the log file
MAX_NB_SPRITES_TO_DOWNLOAD_AT_ONCE=5
CUSTOM_SPRITES_REPO_URL = "https://bitbucket.org/infinitefusionsprites/customsprites/raw/main/CustomBattlers/"
CUSTOM_SPRITES_NEW_URL = "https://infinitefusion.net/CustomBattlers/"
BASE_POKEMON_ALT_SPRITES_REPO_URL = "https://bitbucket.org/infinitefusionsprites/customsprites/raw/main/Other/BaseSprites/"
BASE_POKEMON_ALT_SPRITES_NEW_URL = "https://infinitefusion.net/Other/BaseSprites/"
BASE_POKEMON_SPRITESHEET_URL = "https://infinitefusion.net/spritesheets/spritesheets_base/"
CUSTOM_FUSIONS_SPRITESHEET_URL = "https://infinitefusion.net/spritesheets/spritesheets_custom/"
BASE_POKEMON_SPRITESHEET_TRUE_SIZE_URL = ""
CUSTOM_FUSIONS_SPRITESHEET_TRUE_SIZE_URL = ""
RIVAL_STARTER_PLACEHOLDER_SPECIES = :MEW #(MEW)
VAR_1_PLACEHOLDER_SPECIES = :DIALGA
VAR_2_PLACEHOLDER_SPECIES = :PALKIA
VAR_3_PLACEHOLDER_SPECIES = :GIRATINA
RIVAL_STARTER_PLACEHOLDER_VARIABLE = 250
OVERRIDE_BATTLE_LEVEL_SWITCH = 785
OVERRIDE_BATTLE_LEVEL_VALUE_VAR = 240
HARD_MODE_LEVEL_MODIFIER = 1.1
ZAPMOLCUNO_NB = 999999#176821
MAPS_WITHOUT_SURF_MUSIC = [762]
WONDERTRADE_BASE_URL = "http://localhost:8080"
WONDERTRADE_PUBLIC_KEY = "http://localhost:8080"
MAX_NB_OUTFITS=99
OUTFIT_PREVIEW_PICTURE_ID=20
DEFAULT_TRAINER_CARD_BG="BLUE"
# The generation that the battle system follows. Used throughout the battle
# scripts, and also by some other settings which are used in and out of battle
# (you can of course change those settings to suit your game).
# Note that this isn't perfect. Essentials doesn't accurately replicate every
# single generation's mechanics. It's considered to be good enough. Only
# generations 5 and later are reasonably supported.
MECHANICS_GENERATION = 5
#=============================================================================
# The default screen width (at a scale of 1.0).
SCREEN_WIDTH = 512
# The default screen height (at a scale of 1.0).
SCREEN_HEIGHT = 384
# The default screen scale factor. Possible values are 0.5, 1.0, 1.5 and 2.0.
SCREEN_SCALE = 1.0
FADEOUT_SPEED = 0.2
#=============================================================================
# The maximum level Pokémon can reach.
MAXIMUM_LEVEL = 100
# The level of newly hatched Pokémon.
EGG_LEVEL = 1
# Number of badges in the game
NB_BADGES = 16
# The odds of a newly generated Pokémon being shiny (out of 65536).
SHINY_POKEMON_CHANCE = 16#(MECHANICS_GENERATION >= 6) ? 16 : 8
# The odds of a wild Pokémon/bred egg having Pokérus (out of 65536).
POKERUS_CHANCE = 3
# Whether a bred baby Pokémon can inherit any TM/HM moves from its father. It
# can never inherit TM/HM moves from its mother.
BREEDING_CAN_INHERIT_MACHINE_MOVES = (MECHANICS_GENERATION <= 5)
# Whether a bred baby Pokémon can inherit egg moves from its mother. It can
# always inherit egg moves from its father.
BREEDING_CAN_INHERIT_EGG_MOVES_FROM_MOTHER = (MECHANICS_GENERATION >= 6)
KANTO_STARTERS = [:BULBASAUR, :CHARMANDER, :SQUIRTLE]
JOHTO_STARTERS = [:CHIKORITA, :CYNDAQUIL, :TOTODILE]
HOENN_STARTERS = [:TREECKO, :TORCHIC, :MUDKIP]
SINNOH_STARTERS = [:TURTWIG, :CHIMCHAR, :PIPLUP]
KALOS_STARTERS = [:CHESPIN, :FENNEKIN, :FROAKIE]
#=============================================================================
# The amount of money the player starts the game with.
INITIAL_MONEY = 3000
# The maximum amount of money the player can have.
MAX_MONEY = 999_999
# The maximum number of Game Corner coins the player can have.
MAX_COINS = 99_999
# The maximum number of Battle Points the player can have.
MAX_BATTLE_POINTS = 9_999
# The maximum amount of soot the player can have.
MAX_SOOT = 9_999
# The maximum length, in characters, that the player's name can be.
MAX_PLAYER_NAME_SIZE = 10
# The maximum number of Pokémon that can be in the party.
MAX_PARTY_SIZE = 6
#=============================================================================
# A set of arrays each containing a trainer type followed by a Global Variable
# number. If the variable isn't set to 0, then all trainers with the
# associated trainer type will be named as whatever is in that variable.
RIVAL_NAMES = [
[:RIVAL1, 12],
[:RIVAL2, 12],
[:CHAMPION, 12]
]
#=============================================================================
# Whether outdoor maps should be shaded according to the time of day.
TIME_SHADING = true
#=============================================================================
# Whether poisoned Pokémon will lose HP while walking around in the field.
POISON_IN_FIELD = true #(MECHANICS_GENERATION <= 4)
# Whether poisoned Pokémon will faint while walking around in the field
# (true), or survive the poisoning with 1 HP (false).
POISON_FAINT_IN_FIELD = (MECHANICS_GENERATION >= 3)
# Whether planted berries grow according to Gen 4 mechanics (true) or Gen 3
# mechanics (false).
NEW_BERRY_PLANTS = (MECHANICS_GENERATION >= 4)
# Whether fishing automatically hooks the Pokémon (true), or whether there is
# a reaction test first (false).
FISHING_AUTO_HOOK = false
# The ID of the common event that runs when the player starts fishing (runs
# instead of showing the casting animation).
FISHING_BEGIN_COMMON_EVENT = -1
# The ID of the common event that runs when the player stops fishing (runs
# instead of showing the reeling in animation).
FISHING_END_COMMON_EVENT = -1
#=============================================================================
# The number of steps allowed before a Safari Zone game is over (0=infinite).
SAFARI_STEPS = 600
# The number of seconds a Bug Catching Contest lasts for (0=infinite).
BUG_CONTEST_TIME = 20 * 60 # 20 minutes
#=============================================================================
# Pairs of map IDs, where the location signpost isn't shown when moving from
# one of the maps in a pair to the other (and vice versa). Useful for single
# long routes/towns that are spread over multiple maps.
# e.g. [4,5,16,17,42,43] will be map pairs 4,5 and 16,17 and 42,43.
# Moving between two maps that have the exact same name won't show the
# location signpost anyway, so you don't need to list those maps here.
NO_SIGNPOSTS = []
#=============================================================================
# Whether you need at least a certain number of badges to use some hidden
# moves in the field (true), or whether you need one specific badge to use
# them (false). The amounts/specific badges are defined below.
FIELD_MOVES_COUNT_BADGES = true
# Depending on FIELD_MOVES_COUNT_BADGES, either the number of badges required
# to use each hidden move in the field, or the specific badge number required
# to use each move. Remember that badge 0 is the first badge, badge 1 is the
# second badge, etc.
# e.g. To require the second badge, put false and 1.
# To require at least 2 badges, put true and 2.
BADGE_FOR_CUT = 1
BADGE_FOR_FLASH = 1
BADGE_FOR_ROCKSMASH = 0
BADGE_FOR_SURF = 6
BADGE_FOR_FLY = 3
BADGE_FOR_STRENGTH = 5
BADGE_FOR_DIVE = 9
BADGE_FOR_WATERFALL = 9
BADGE_FOR_TELEPORT = 3
BADGE_FOR_BOUNCE = 8
BADGE_FOR_ROCKCLIMB = 16
#=============================================================================
# If a move taught by a TM/HM/TR replaces another move, this setting is
# whether the machine's move retains the replaced move's PP (true), or whether
# the machine's move has full PP (false).
TAUGHT_MACHINES_KEEP_OLD_PP = (MECHANICS_GENERATION == 5)
# Whether the Black/White Flutes will raise/lower the levels of wild Pokémon
# respectively (true), or will lower/raise the wild encounter rate
# respectively (false).
FLUTES_CHANGE_WILD_ENCOUNTER_LEVELS = (MECHANICS_GENERATION >= 6)
# Whether Repel uses the level of the first Pokémon in the party regardless of
# its HP (true), or it uses the level of the first unfainted Pokémon (false).
REPEL_COUNTS_FAINTED_POKEMON = (MECHANICS_GENERATION >= 6)
# Whether Rage Candy Bar acts as a Full Heal (true) or a Potion (false).
RAGE_CANDY_BAR_CURES_STATUS_PROBLEMS = (MECHANICS_GENERATION >= 7)
#=============================================================================
# The name of the person who created the Pokémon storage system.
def self.storage_creator_name
return _INTL("Bill")
end
# The number of boxes in Pokémon storage.
NUM_STORAGE_BOXES = 40
#=============================================================================
# The names of each pocket of the Bag. Ignore the first entry ("").
def self.bag_pocket_names
return ["",
_INTL("Items"),
_INTL("Medicine"),
_INTL("Poké Balls"),
_INTL("TMs & HMs"),
_INTL("Berries"),
_INTL("Mail"),
_INTL("Battle Items"),
_INTL("Key Items")
]
end
# The maximum number of slots per pocket (-1 means infinite number). Ignore
# the first number (0).
BAG_MAX_POCKET_SIZE = [0, -1, -1, -1, -1, -1, -1, -1, -1]
# The maximum number of items each slot in the Bag can hold.
BAG_MAX_PER_SLOT = 999
# Whether each pocket in turn auto-sorts itself by item ID number. Ignore the
# first entry (the 0).
BAG_POCKET_AUTO_SORT = [0, false, false, false, true, true, false, false, false]
#=============================================================================
# Whether the Pokédex list shown is the one for the player's current region
# (true), or whether a menu pops up for the player to manually choose which
# Dex list to view if more than one is available (false).
USE_CURRENT_REGION_DEX = false
# The names of the Pokédex lists, in the order they are defined in the PBS
# file "regionaldexes.txt". The last name is for the National Dex and is added
# onto the end of this array (remember that you don't need to use it). This
# array's order is also the order of $Trainer.pokedex.unlocked_dexes, which
# records which Dexes have been unlocked (the first is unlocked by default).
# If an entry is just a name, then the region map shown in the Area page while
# viewing that Dex list will be the region map of the region the player is
# currently in. The National Dex entry should always behave like this.
# If an entry is of the form [name, number], then the number is a region
# number. That region's map will appear in the Area page while viewing that
# Dex list, no matter which region the player is currently in.
def self.pokedex_names
return [
# [_INTL("Kanto Pokédex"), 0]
]
end
# Whether all forms of a given species will be immediately available to view
# in the Pokédex so long as that species has been seen at all (true), or
# whether each form needs to be seen specifically before that form appears in
# the Pokédex (false).
DEX_SHOWS_ALL_FORMS = false
# An array of numbers, where each number is that of a Dex list (in the same
# order as above, except the National Dex is -1). All Dex lists included here
# will begin their numbering at 0 rather than 1 (e.g. Victini in Unova's Dex).
DEXES_WITH_OFFSETS = []
#=============================================================================
# A set of arrays, each containing details of a graphic to be shown on the
# region map if appropriate. The values for each array are as follows:
# * Region number.
# * Game Switch; the graphic is shown if this is ON (non-wall maps only).
# * X coordinate of the graphic on the map, in squares.
# * Y coordinate of the graphic on the map, in squares.
# * Name of the graphic, found in the Graphics/Pictures folder.
# * The graphic will always (true) or never (false) be shown on a wall map.
REGION_MAP_EXTRAS = [
#[0, 51, 16, 15, "mapHiddenBerth", false],
#[0, 52, 20, 14, "mapHiddenFaraday", false]
]
TRIPLE_TYPES = [:QMARKS,:ICEFIREELECTRIC,:FIREWATERELECTRIC,:WATERGROUNDFLYING,:GHOSTSTEELWATER,
:FIREWATERGRASS,:GRASSSTEEL,:BUGSTEELPSYCHIC,:ICEROCKSTEEL]
#=============================================================================
# A list of maps used by roaming Pokémon. Each map has an array of other maps
# it can lead to.
ROAMING_AREAS = {
262 => [261,311],
311 => [262,312],
312 => [311],
261 => [262,288,267],
288 => [261,267,285],
267 => [261,288,300,254],
284 => [288,266,285],
300 => [267,254],
254 => [300,265],
266 => [284,265],
265 => [266,254],
285 => [284,288]}
SEVII_ROAMING = {
528 => [526], #Treasure beach
526 => [528,559], #Knot Island
559 => [526,561,564], #Kindle Road
561 => [559], #Mt. Ember
564 => [559,562,563,594], #brine road
562 => [564], #boon island
563 => [564,600] , #kin island
594 => [564,566,603], #water labyrinth
600 => [563,619], #bond bridge
619 => [600] , #Berry forest
566 => [594,603], #Resort gorgeous
603 => [566,594], #Chrono Island
}
# A set of arrays, each containing the details of a roaming Pokémon. The
# information within each array is as follows:
# * Species.
# * Level.
# * Game Switch; the Pokémon roams while this is ON.
# * Encounter type (0=any, 1=grass/walking in cave, 2=surfing, 3=fishing,
# 4=surfing/fishing). See the bottom of PField_RoamingPokemon for lists.
# * Name of BGM to play for that encounter (optional).
# * Roaming areas specifically for this Pokémon (optional).
ROAMING_SPECIES = [
# {
# :species => :LATIAS,
# :level => 30,
# :icon => "pin_latias",
# :game_switch => 53,
# :encounter_type => :all,
# :bgm => "Battle roaming"
# },
# {
# :species => :LATIOS,
# :level => 30,
# :icon => "pin_latios",
# :game_switch => 53,
# :encounter_type => :all,
# :bgm => "Battle roaming"
# },
# {
# :species => :KYOGRE,
# :level => 40,
# :game_switch => 54,
# :encounter_type => :surfing,
# :areas => {
# 2 => [ 21, 31 ],
# 21 => [2, 31, 69],
# 31 => [2, 21, 69],
# 69 => [ 21, 31 ]
# }
# },
# {
# :species => :ENTEI,
# :level => 40,
# :icon => "pin_entei",
# :game_switch => 55,
# :encounter_type => :land
# }
]
PINKAN_ISLAND_MAPS=[51,46,428,531]
#=============================================================================
# A set of arrays, each containing the details of a wild encounter that can
# only occur via using the Poké Radar. The information within each array is as
# follows:
# * Map ID on which this encounter can occur.
# * Probability that this encounter will occur (as a percentage).
# * Species.
# * Minimum possible level.
# * Maximum possible level (optional).
POKE_RADAR_ENCOUNTERS = [
[78, 50, :FLETCHLING,2,5], #Rt. 1
[86, 50, :FLETCHLING,2,5], #Rt. 2
[90, 50, :FLETCHLING,2,5], #Rt. 2
[491, 50, :SHROOMISH,2,5], #Viridian Forest
[490, 50, :BUDEW,4,9], #Rt. 3
[106, 50, :NINCADA,8,10], #Rt. 4
[12, 50, :TOGEPI,10,10], #Rt. 5
[16, 50, :SLAKOTH,12,15], #Rt. 6
[413, 50, :DRIFLOON,17,20], #Rt. 7
[409, 50, :SHINX,17,18], #Rt. 8
[495, 50, :ARON,12,15], #Rt. 9
[351, 50, :ARON,12,15], #Rt. 9
[154, 50, :KLINK,14,17], #Rt. 10
[155, 50, :NINCADA,12,15], #Rt. 11
[159, 50, :COTTONEE,22,25], #Rt. 12
[437, 50, :COTTONEE,22,25], #Rt. 13
[437, 50, :JOLTIK,22,25], #Rt. 13
[440, 50, :JOLTIK,22,25], #Rt. 14
[444, 50, :SOLOSIS,22,25], #Rt. 15
[438, 50, :NATU,22,25], #Rt. 16
[146, 50, :KLEFKI,22,25], #Rt. 17
[517, 50, :FERROSEED,22,25], #Rt. 18
[445, 50, :BAGON,20,20], #Safari zone 1
[484, 50, :AXEW,20,20], #Safari zone 2
[485, 50, :DEINO,20,20], #Safari zone 3
[486, 50, :LARVITAR,20,20], #Safari zone 4
[487, 50, :JANGMOO,20,20], #Safari zone 5
[59, 50, :DUNSPARCE,25,30], #Rt. 21
[171, 50, :BIDOOF,2,5], #Rt. 22
[143, 50, :RIOLU,25,25], #Rt. 23
[8, 50, :BUNEARY,12,13], #Rt. 24
[145, 50, :ABSOL,30,35], #Rt. 26
[147, 50, :ABSOL,30,35], #Rt. 27
[311, 50, :BIDOOF,5,5], #Rt. 29
[284, 50, :LUXIO,40,45], #Rt. 33
[288, 50, :VIGOROTH,40,45], #Rt. 32
[342, 50, :GOLETT,40,45], #Ruins of Alph
[261, 50, :BELLOSSOM,45,50], #Rt. 31
[262, 50, :BIBAREL,45,50], #Rt. 30
[265, 50, :KIRLIA,25,30], #Rt. 34
[254, 50, :SMEARGLE,25,30], #Rt. 35
[267, 50, :SUDOWOODO,25,30], #Rt. 36
[500, 50, :FOMANTIS,30,30], #National Park
[266, 50, :BRELOOM,30,30], #Ilex Forest
[670, 50, :WEAVILE,50,50], #Ice mountains
[528, 50, :PYUKUMUKU,20,20], #Treasure Beach
[690, 50, :OCTILLERY,32,45], #Deep Ocean
[561, 50, :FLETCHINDER,32,45], #Mt. Ember
[562, 50, :NINJASK,45,50], #Boon Island
[603, 50, :KECLEON,45,50], #Chrono Island
[654, 50, :WHIMSICOTT,32,45], #Brine Road
[559, 50, :SCRAGGY,32,45] #Kindle Road
]
#=============================================================================
# The Game Switch that is set to ON when the player blacks out.
STARTING_OVER_SWITCH = 1
# The Game Switch that is set to ON when the player has seen Pokérus in the
# Poké Center (and doesn't need to be told about it again).
SEEN_POKERUS_SWITCH = 2
# The Game Switch which, while ON, makes all wild Pokémon created be shiny.
SHINY_WILD_POKEMON_SWITCH = 31
# The Game Switch which, while ON, makes all Pokémon created considered to be
# met via a fateful encounter.
FATEFUL_ENCOUNTER_SWITCH = 32
#=============================================================================
# ID of the animation played when the player steps on grass (grass rustling).
GRASS_ANIMATION_ID = 1
# ID of the animation played when the player lands on the ground after hopping
# over a ledge (shows a dust impact).
DUST_ANIMATION_ID = 2
# ID of the animation played when a trainer notices the player (an exclamation
# bubble).
EXCLAMATION_ANIMATION_ID = 3
# ID of the animation played when a patch of grass rustles due to using the
# Poké Radar.
RUSTLE_NORMAL_ANIMATION_ID = 1
# ID of the animation played when a patch of grass rustles vigorously due to
# using the Poké Radar. (Rarer species)
RUSTLE_VIGOROUS_ANIMATION_ID = 5
# ID of the animation played when a patch of grass rustles and shines due to
# using the Poké Radar. (Shiny encounter)
RUSTLE_SHINY_ANIMATION_ID = 6
# ID of the animation played when a berry tree grows a stage while the player
# is on the map (for new plant growth mechanics only).
PLANT_SPARKLE_ANIMATION_ID = 7
SLEEP_ANIMATION_ID = 26
CUT_TREE_ANIMATION_ID = 19
ROCK_SMASH_ANIMATION_ID = 20
#=============================================================================
# An array of available languages in the game, and their corresponding message
# file in the Data folder. Edit only if you have 2 or more languages to choose
# from.
LANGUAGES = [
# ["English", "english.dat"],
# ["Deutsch", "deutsch.dat"]
]
#Technical
SPRITE_CACHE_MAX_NB=100
NEWEST_SPRITEPACK_MONTH = 12
NEWEST_SPRITEPACK_YEAR = 2020
#=============================================================================
# Available speech frames. These are graphic files in "Graphics/Windowskins/".
SPEECH_WINDOWSKINS = [
"speech hgss 1",
"speech hgss 2",
"speech hgss 3",
"speech hgss 4",
"speech hgss 5",
"speech hgss 6",
"speech hgss 7",
"speech hgss 8",
"speech hgss 9",
"speech hgss 10",
"speech hgss 11",
"speech hgss 12",
"speech hgss 13",
"speech hgss 14",
"speech hgss 15",
"speech hgss 16",
"speech hgss 17",
"speech hgss 18",
"speech hgss 19",
"speech hgss 20",
"speech pl 18"
]
# Available menu frames. These are graphic files in "Graphics/Windowskins/".
MENU_WINDOWSKINS = [
"default_transparent",
"default_opaque",
"choice 2",
"choice 3",
"choice 4",
"choice 5",
"choice 6",
"choice 7",
"choice 8",
"choice 9",
"choice 10",
"choice 11",
"choice 12",
"choice 13",
"choice 14",
"choice 15",
"choice 16",
"choice 17",
"choice 18",
"choice 19",
"choice 20",
"choice 21",
"choice 22",
"choice 23",
"choice 24",
"choice 25",
"choice 26",
"choice 27",
"choice 28"
]
RANDOMIZED_GYM_TYPE_TM=
{
:NORMAL => [:TM32,:TM49,:TM42,:TM98], #DOUBLETEAM ECHOEDVOICE FACADE BATONPASS
:FIGHTING => [:TM83,:TM115,:TM52,:TM112], #WORKUP POWERUPPUNCH FOCUSBLAST FOCUSPUNCH
:FLYING => [:TM62,:TM58,:TM108,:TM100], #ACROBATICS SKYDROP SKYATTACK DEFOG
:POISON => [:TM84,:TM06,:TM36,:TM34], #POISONJAB TOXIC SLUDGEBOMB SLUDGEWAVE
:GROUND => [:TM28,:TM78,:TM26,:TM119], #DIG BULLDOZE EARTHQUAKE STOMPINGTANTRUM
:ROCK => [:TM39,:TM80,:TM71,:TM69], #ROCKTOMB ROCKTHROW STONEDGE ROCKPOLISH
:BUG => [:TM76,:TM89,:TM113,:TM99], #STRUGGLEBUG UTURN INFESTATION QUIVERDANCE
:GHOST => [:TM85,:TM65,:TM30,:TM97], #DREAMEATER SHADOWCLAW SHADOWBALL NASTYPLOT
:STEEL => [:TM74,:TM118,:TM117,:TM75], # GYROBALL STEELWING SMARTSTRIKE SWORDDANCE
:FIRE => [:TM11,:TM43,:TM38,:TM61], #SUNNYDAY FLAMECHARGE FIREBLAST WILLOWISP
:WATER => [:TM55,:TM105,:TM121,:TM18], #WATERPULSE AQUAJET SCALD RAINDANCE
:GRASS => [:TM22,:TM53,:TM86,:TM102], # SOLARBEAM ENERGYBALL GRASSKNOT SPORE
:ELECTRIC => [:TM73,:TM116,:TM93,:TM72], #THUNDERWAVE SHOCKWAVE WILDCHARGE VOLTSWITCH
:PSYCHIC => [:TM77,:TM03,:TM29,:TM04], #PSYCHUP PSYSHOCK PSYCHIC CALMMIND
:ICE => [:TM110,:TM13,:TM14,:TM07], #AURORAVEIL ICEBEAM BLIZZARD HAIL
:DRAGON => [:TM95,:TM02,:TM82,:TM101], #SNARL DRAGONCLAW DRAGONTAIL DRAGONDANCE
:DARK => [:TM95,:TM46,:TM120,:TM97], #SNARL THIEF THROATCHOP NASTYPLOT
:FAIRY => [:TM45,:TM111,:TM96,:TM104] #ATTRACT DAZZLINGGLEAM MOONBLAST RECOVER
}
EXCLUDE_FROM_RANDOM_SHOPS=[:RARECANDY]
end
# DO NOT EDIT THESE!
module Essentials
VERSION = "19.1.dev"
ERROR_TEXT = ""
end

View File

@@ -0,0 +1,128 @@
# ###################
# ## NEW POKEBALLS #
# ###################
#
# #GENDER BALL (24) - switch le gender du pokemon
# #catch rate: pokeball
# BallHandlers::OnCatch.add(:GENDERBALL,proc{|ball,battle,pokemon|
# if pokemon.gender == 0
# pokemon.makeFemale
# elsif pokemon.gender == 1
# pokemon.makeMale
# end
# })
#
# #BOOST BALL 25 - rend le pokemon traded
# #catch rate: 80% pokeball
# BallHandlers::ModifyCatchRate.add(:TRADEBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.8).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:TRADEBALL,proc{|ball,battle,pokemon|
# pokemon.obtain_method = 2
# })
#
# #ABILITY BALL 26 - change l'ability
# #catch rate: 60% pokeball
# BallHandlers::ModifyCatchRate.add(:ABILITYBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.6).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:ABILITYBALL,proc{|ball,battle,pokemon|
# species = getSpecies(dexNum(pokemon))
# ability = species.hidden_abilities[-1]
# pokemon.ability = ability
# pokemon.ability_index= getAbilityIndexFromID(ability,pokemon)
# })
#
# #VIRUS BALL 27 - give pokerus
# #catch rate: 40% pokeball
# BallHandlers::ModifyCatchRate.add(:VIRUSBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.4).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:VIRUSBALL,proc{|ball,battle,pokemon|
# pokemon.givePokerus
# })
#
# #SHINY BALL 28 - rend shiny
# #catchrate: 20% pokeball
# BallHandlers::ModifyCatchRate.add(:SHINYBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.2).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:SHINYBALL,proc{|ball,battle,pokemon|
# pokemon.glitter=true
# })
#
# #PERFECTBALL 29
# #catch rate: 10% pokeball
# BallHandlers::ModifyCatchRate.add(:PERFECTBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.1).floor(1)
# next catchRate
# })
# BallHandlers::OnCatch.add(:PERFECTBALL,proc{|ball,battle,pokemon|
# stats = [:ATTACK, :SPECIAL_ATTACK, :SPECIAL_DEFENSE, :SPEED, :DEFENSE, :HP]
# first = rand(stats.length)
# second = rand(stats.length)
# pokemon.iv[stats[first]] = 31
# pokemon.iv[stats[second]] = 31
# })
#
#
# #DREAMBALL - endormi
# BallHandlers::ModifyCatchRate.add(:DREAMBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :SLEEP
# next catchRate
# })
# #TOXICBALL - empoisonné
# BallHandlers::ModifyCatchRate.add(:TOXICBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :POISON
# next catchRate
# })
# #SCORCHBALL - brulé
# BallHandlers::ModifyCatchRate.add(:SCORCHBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :BURN
# next catchRate
# })
# #FROSTBALL - frozen
# BallHandlers::ModifyCatchRate.add(:FROSTBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :FROZEN
# next catchRate
# })
# #SPARKBALL - paralizé
# BallHandlers::ModifyCatchRate.add(:SPARKBALL,proc{|ball,catchRate,battle,battler|
# battler.status = :PARALYSIS
# next catchRate
# })
# #PUREBALL - marche mieux quand pas de status
# BallHandlers::ModifyCatchRate.add(:PUREBALL,proc{|ball,catchRate,battle,battler|
# catchRate=(catchRate*7/2).floor if battler.status ==0
# next catchRate
# })
# #STATUSBALL - marche mieux quand any status
# BallHandlers::ModifyCatchRate.add(:STATUSBALL,proc{|ball,catchRate,battle,battler|
# catchRate=(catchRate*5/2).floor if battler.status !=0
# next catchRate
# })
#
# #FUSIONBALL - marche mieux quand fusedr
# BallHandlers::ModifyCatchRate.add(:FUSIONBALL,proc{|ball,catchRate,battle,battler|
# catchRate*=3 if GameData::Species.get(battler.species).id_number > Settings::NB_POKEMON
# next catchRate
# })
#
# #CANDY BALL - +5 level
# #catchrate: 80% pokeball
# BallHandlers::ModifyCatchRate.add(:CANDYBALL,proc{|ball,catchRate,battle,pokemon|
# catchRate=(catchRate*0.8).floor
# next catchRate
# })
# BallHandlers::OnCatch.add(:CANDYBALL,proc{|ball,battle,pokemon|
# pokemon.level = pokemon.level+5
# })
# #FIRECRACKER
# BallHandlers::ModifyCatchRate.add(:FIRECRACKER,proc{|ball,catchRate,battle,battler|
# battler.hp -= 10
# next 0
# })

View File

@@ -0,0 +1,141 @@
#===============================================================================
# Rock Smash
#===============================================================================
def pbRockSmashRandomEncounter
if rand(100)<30
if pbEncounter(:RockSmash)
return
else
pbDefaultRockSmashEncounter(5,15)
end
else
rockSmashItem(false)
end
end
def pbDefaultRockSmashEncounter(minLevel,maxLevel)
level =rand((maxLevel-minLevel).abs)+minLevel
pbWildBattle(:GEODUDE,level)
return true
end
#FOR ROCK TUNNEL AND CERULEAN CAVE (+diamond)
def pbRockSmashRandomEncounterSpecial
if rand(100)<35
pbEncounter(:RockSmash)
else
rockSmashItem(true)
end
end
def getRockSmashItemList(inclRareItems)
basicItems = [:ROCKGEM, :GROUNDGEM,:STEELGEM,
:HARDSTONE,:HARDSTONE,:HARDSTONE,:ROCKGEM,
:SMOOTHROCK,:STARDUST,:HEARTSCALE,:HEARTSCALE,
:HEARTSCALE,:SOFTSAND,:HEARTSCALE,:RAREBONE]
rareItems = [:RAREBONE,:STARDUST,:ETHER,
:REVIVE,:NUGGET,:DIAMOND]
fossilItems = [:ROOTFOSSIL,:CLAWFOSSIL,:DOMEFOSSIL,:HELIXFOSSIL,
:SKULLFOSSIL,:ARMORFOSSIL,:JAWFOSSIL,:SAILFOSSIL]
# Kernel.pbMessage(inclRareItems.to_s)
itemsList = inclRareItems ? basicItems + basicItems + rareItems : basicItems
#beaten league
if $game_switches[12]
itemsList += fossilItems
end
return itemsList
end
def rockSmashItem(isDark=false)
chance = 50
if rand(100)< chance
if rand(5) == 0 && !hatUnlocked?(HAT_AERODACTYL)
obtainHat(HAT_AERODACTYL)
else
itemsList = getRockSmashItemList(isDark)
i = rand(itemsList.length)
Kernel.pbItemBall(itemsList[i],1,nil,false)
end
end
end
#Used in underwater maps
def pbRockSmashRandomEncounterDive
if rand(100)<25
pbEncounter(:RockSmash)
else
if rand(100)<20
itemsList = [:WATERGEM,:STEELGEM,
:HEARTSCALE,:HEARTSCALE,:HARDSTONE,:ROCKGEM,
:SMOOTHROCK,:WATERSTONE,:PEARL,:HEARTSCALE,
:HEARTSCALE,:HEARTSCALE,:SHOALSHELL,:BIGPEARL]
i = rand(itemsList.length)
Kernel.pbItemBall(itemsList[i],1,nil,false)
end
end
end
############### MORNING SUN / MOONLIGHT
HiddenMoveHandlers::CanUseMove.add(:MORNINGSUN,proc{|move,pkmn|
mapMetadata = GameData::MapMetadata.try_get($game_map.map_id)
if !mapMetadata || !mapMetadata.outdoor_map
Kernel.pbMessage(_INTL("Can't use that here."))
next false
end
next true
})
HiddenMoveHandlers::UseMove.add(:MORNINGSUN,proc{|move,pokemon|
Kernel.pbMessage(_INTL("{1} used {2}!",pokemon.name,GameData::Move.get(move).name))
pbHiddenMoveAnimation(pokemon)
pbFadeOutIn(99999){
pbSkipTime(9)
newTime = pbGetTimeNow.strftime("%I:%M %p")
Kernel.pbMessage(_INTL("{1} waited until morning...",$Trainer.name))
Kernel.pbMessage(_INTL("The time is now {1}",newTime))
$game_screen.weather(:None,0,0)
$game_map.refresh
}
next true
})
HiddenMoveHandlers::CanUseMove.add(:MOONLIGHT,proc{|move,pkmn|
mapMetadata = GameData::MapMetadata.try_get($game_map.map_id)
if !mapMetadata || !mapMetadata.outdoor_map
Kernel.pbMessage(_INTL("Can't use that here."))
next false
end
next true
})
HiddenMoveHandlers::UseMove.add(:MOONLIGHT,proc{|move,pokemon|
Kernel.pbMessage(_INTL("{1} used {2}!",pokemon.name,GameData::Move.get(move).name))
pbHiddenMoveAnimation(pokemon)
pbFadeOutIn(99999){
pbSkipTime(21)
newTime = pbGetTimeNow.strftime("%I:%M %p")
Kernel.pbMessage(_INTL("{1} waited until night...",$Trainer.name))
Kernel.pbMessage(_INTL("The time is now {1}",newTime))
$game_screen.weather(:None,0,0)
$game_map.refresh
}
next true
})
def pbSkipTime(newTime)
currentTime = pbGetTimeNow.hour
hoursToAdd = newTime - currentTime
$game_variables[UnrealTime::EXTRA_SECONDS] += hoursToAdd*3600
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,409 @@
def find_last_outfit(outfit_type_path, firstOutfit)
for i in firstOutfit..Settings::MAX_NB_OUTFITS
outfit_path = outfit_type_path + "/" + i.to_s #Settings::PLAYER_GRAPHICS_FOLDER + outfit_type_path + "/" + outfit_type_path + "_" + player_sprite + "_" + i.to_s
return i - 1 if !Dir.exist?(outfit_path)
end
return firstOutfit
end
def list_all_numeric_folders(directory_path)
entries = Dir.entries(directory_path)
# Filter out only the directories whose names are numeric (excluding "." and "..")
numeric_folders = entries.select do |entry|
full_path = File.join(directory_path, entry)
File.directory?(full_path) && entry != '.' && entry != '..' && entry.match?(/^\d+$/)
end
# Convert the folder names to integers and store in an array
folder_integers = numeric_folders.map(&:to_i)
folder_integers.sort!
return folder_integers
end
def list_all_numeric_files_with_filter(directory_path, prefix)
entries = Dir.entries(directory_path)
prefixless = []
for file in entries
next if file == "." || file == ".."
prefixless << file.gsub((prefix + "_"), "")
end
folder_integers = prefixless.map(&:to_i)
folder_integers.sort!
return folder_integers
end
#unlocked:
# -1 for all outfits unlocked
# Otherwise, an array of the ids of unlocked outfits
def list_available_outfits(directory, versions = [], unlocked = [], prefix_filter = nil)
if prefix_filter
outfits = list_all_numeric_files_with_filter(directory, prefix_filter)
else
outfits = list_all_numeric_folders(directory)
end
# #echoln outfits
# return outfits #todo: remove this return for unlockable outfits
available_outfits = []
for outfit in outfits
if !unlocked || unlocked.include?(outfit)
for version in versions
available_outfits << outfit.to_s + version
end
available_outfits << outfit.to_s if versions.empty?
end
end
return available_outfits
end
def get_current_outfit_position(currentOutfit_id, available_outfits)
current_index = available_outfits.index(currentOutfit_id)
return current_index.nil? ? 0 : current_index
end
def setHairColor(hue_shift)
$Trainer.hair_color = hue_shift
refreshPlayerOutfit()
end
def shiftHatColor(incr,secondary_hat=false)
if secondary_hat
$Trainer.hat2_color = 0 if !$Trainer.hat2_color
$Trainer.hat2_color += incr
else
$Trainer.hat_color = 0 if !$Trainer.hat_color
$Trainer.hat_color += incr
end
refreshPlayerOutfit()
end
def shiftClothesColor(incr)
$Trainer.clothes_color = 0 if !$Trainer.clothes_color
$Trainer.clothes_color += incr
refreshPlayerOutfit()
end
def shiftHairColor(incr)
$Trainer.hair_color = 0 if !$Trainer.hair_color
$Trainer.hair_color += incr
echoln "Hair color: #{$Trainer.hair_color}"
refreshPlayerOutfit()
end
def pbLoadOutfitBitmap(outfitFileName)
begin
outfitBitmap = RPG::Cache.load_bitmap("", outfitFileName)
return outfitBitmap
rescue
return nil
end
end
def setOutfit(outfit_id)
$Trainer.clothes = outfit_id
end
def setHat(hat_id)
$Trainer.hat = hat_id
end
def getEasterEggHeldItem()
map = $game_map.map_id
return "secrets/HOTDOG" if [141, 194].include?(map) #restaurant
return "secrets/SNOWBALL" if [670, 693, 698, 694].include?(map)
return "secrets/WALLET" if [432, 433, 434, 435, 436, 292].include?(map) #dept. store
return "secrets/ALARMCLOCK" if [43, 48, 67, 68, 69, 70, 71, 73].include?(map) #Player room
return "SAFARIBALL" if [445, 484, 485, 486, 107, 487, 488, 717, 82, 75, 74].include?(map) #Safari Zone
return "secrets/WISP" if [401,402,403,467,468,469].include?(map) #Pokemon Tower
return "secrets/SKULL" if [400].include?(map) #Pokemon Tower ground floor
return "secrets/ROCK" if [349,350,800,].include?(map) #Rock Tunnel
return "secrets/MAGIKARP" if [394,471,189,].include?(map) #Fishing huts
return "secrets/AZUREFLUTE" if [694,].include?(map) && $PokemonBag.pbQuantity(:AZUREFLUTE)>=1 #Ice Mountain peak
return "secrets/BIGSODA" if [436,].include?(map) && $PokemonBag.pbQuantity(:SODAPOP)>=1 #Celadon dept. store top
return "secrets/EGG" if [13,406,214,].include?(map) #Day care
return "secrets/STICK" if [266,].include?(map) #Ilex forest
return "secrets/BANANA" if [600,].include?(map) #Bond Bridge
return "secrets/BERRY" if [619,620,].include?(map) #Berry forest
return "secrets/COIN" if [357].include?(map) #Pokemart
return "secrets/LATTE" if [406].include?(map) #Celadon Café
return nil
end
def getCurrentPokeball(allowEasterEgg=true)
otherItem = getEasterEggHeldItem() if allowEasterEgg
return otherItem if otherItem
firstPokemon = $Trainer.party[0]
return firstPokemon.poke_ball if firstPokemon
return nil
end
def generate_front_trainer_sprite_bitmap_from_appearance(trainerAppearance)
echoln trainerAppearance.hat
return generate_front_trainer_sprite_bitmap(false,nil,trainerAppearance.clothes,trainerAppearance.hat,trainerAppearance.hat2,
trainerAppearance.hair,trainerAppearance.skin_color,
trainerAppearance.hair_color,trainerAppearance.hat_color,trainerAppearance.clothes_color,
trainerAppearance.hat2_color)
end
def generate_front_trainer_sprite_bitmap(allowEasterEgg=true, pokeball = nil,
clothes_id = nil, hat_id = nil, hat2_id=nil, hair_id = nil,
skin_tone_id = nil, hair_color = nil, hat_color = nil, clothes_color = nil,
hat2_color = nil)
clothes_id = $Trainer.clothes if !clothes_id
hat_id = $Trainer.hat if !hat_id
hat2_id = $Trainer.hat2 if !hat2_id
hair_id = $Trainer.hair if !hair_id
skin_tone_id = $Trainer.skin_tone if !skin_tone_id
hair_color = $Trainer.hair_color if !hair_color
hat_color = $Trainer.hat_color if !hat_color
hat2_color = $Trainer.hat2_color if !hat2_color
clothes_color = $Trainer.clothes_color if !clothes_color
hairFilename = getTrainerSpriteHairFilename(hair_id) #_INTL(Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_HAIR_FOLDER + "/hair_trainer_{1}", $Trainer.hair)
outfitFilename = getTrainerSpriteOutfitFilename(clothes_id) #_INTL(Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_CLOTHES_FOLDER + "/clothes_trainer_{1}", $Trainer.clothes)
hatFilename = getTrainerSpriteHatFilename(hat_id)
hat2Filename = getTrainerSpriteHatFilename(hat2_id)
pokeball = getCurrentPokeball(allowEasterEgg) if !pokeball
ballFilename = getTrainerSpriteBallFilename(pokeball) if pokeball
baseFilePath = getBaseTrainerSpriteFilename(skin_tone_id)
hair_color_shift = hair_color
hat_color_shift = hat_color
hat2_color_shift = hat2_color
clothes_color_shift = clothes_color
hair_color_shift = 0 if !hair_color_shift
hat_color_shift = 0 if !hat_color_shift
hat2_color_shift = 0 if !hat2_color_shift
clothes_color_shift = 0 if !clothes_color_shift
baseBitmap = AnimatedBitmap.new(baseFilePath) if pbResolveBitmap(baseFilePath)
ballBitmap = pbLoadOutfitBitmap(ballFilename) if pbResolveBitmap(ballFilename)
if !pbResolveBitmap(outfitFilename)
outfitFilename = getTrainerSpriteOutfitFilename(Settings::PLAYER_TEMP_OUTFIT_FALLBACK)
end
if !pbResolveBitmap(outfitFilename)
raise "No temp clothes graphics available"
end
outfitBitmap = AnimatedBitmap.new(outfitFilename, clothes_color_shift) if pbResolveBitmap(outfitFilename) #pb
hairBitmapWrapper = AnimatedBitmap.new(hairFilename, hair_color_shift) if pbResolveBitmap(hairFilename)
hatBitmap = AnimatedBitmap.new(hatFilename, hat_color_shift) if pbResolveBitmap(hatFilename)
hat2Bitmap = AnimatedBitmap.new(hat2Filename, hat2_color_shift) if pbResolveBitmap(hat2Filename)
baseBitmap.bitmap = baseBitmap.bitmap.clone
if outfitBitmap
baseBitmap.bitmap.blt(0, 0, outfitBitmap.bitmap, outfitBitmap.bitmap.rect)
else
outfitFilename = getTrainerSpriteOutfitFilename("temp")
outfitBitmap = AnimatedBitmap.new(outfitFilename, 0)
baseBitmap.bitmap.blt(0, 0, outfitBitmap.bitmap, outfitBitmap.bitmap.rect)
end
baseBitmap.bitmap.blt(0, 0, hairBitmapWrapper.bitmap, hairBitmapWrapper.bitmap.rect) if hairBitmapWrapper
baseBitmap.bitmap.blt(0, 0, hat2Bitmap.bitmap, hat2Bitmap.bitmap.rect) if hat2Bitmap
baseBitmap.bitmap.blt(0, 0, hatBitmap.bitmap, hatBitmap.bitmap.rect) if hatBitmap
baseBitmap.bitmap.blt(44, 42, ballBitmap, ballBitmap.rect) if ballBitmap
return baseBitmap
end
def generateNPCClothedBitmapStatic(trainerAppearance,action = "walk")
baseBitmapFilename = getBaseOverworldSpriteFilename(action, trainerAppearance.skin_color)
baseSprite = AnimatedBitmap.new(baseBitmapFilename)
baseBitmap = baseSprite.bitmap.clone # nekkid sprite
outfitFilename = getOverworldOutfitFilename(trainerAppearance.clothes, action)
hairFilename = getOverworldHairFilename(trainerAppearance.hair)
#Clothes
clothes_color_shift = trainerAppearance.clothes_color || 0
clothesBitmap = AnimatedBitmap.new(outfitFilename, clothes_color_shift).bitmap if pbResolveBitmap(outfitFilename)
baseBitmap.blt(0, 0, clothesBitmap, clothesBitmap.rect)
#clothesBitmap.dispose
#Hair
hair_color_shift = trainerAppearance.hair_color || 0
hairBitmap = AnimatedBitmap.new(hairFilename, hair_color_shift).bitmap if pbResolveBitmap(hairFilename)
baseBitmap.blt(0, 0, hairBitmap, hairBitmap.rect)
#Hat
hat_color_shift = trainerAppearance.hat_color || 0
hat2_color_shift = trainerAppearance.hat2_color || 0
hatFilename = getOverworldHatFilename(trainerAppearance.hat)
hat2Filename = getOverworldHatFilename(trainerAppearance.hat2)
hatBitmapWrapper = AnimatedBitmap.new(hatFilename, hat_color_shift) if pbResolveBitmap(hatFilename)
hat2BitmapWrapper = AnimatedBitmap.new(hat2Filename, hat2_color_shift) if pbResolveBitmap(hat2Filename)
if hat2BitmapWrapper
frame_count = 4 # Assuming 4 frames for hair animation; adjust as needed
hat2_frame_bitmap = duplicateHatForFrames(hat2BitmapWrapper.bitmap, frame_count)
frame_width = baseSprite.bitmap.width / frame_count # Calculate frame width
frame_count.times do |i|
# Calculate offset for each frame
frame_offset = [i * frame_width, 0]
# Adjust Y offset if frame index is odd
frame_offset[1] -= 2 if i.odd?
positionHat(baseBitmap, hat2_frame_bitmap, frame_offset, i, frame_width)
end
end
if hatBitmapWrapper
frame_count = 4 # Assuming 4 frames for hair animation; adjust as needed
hat_frame_bitmap = duplicateHatForFrames(hatBitmapWrapper.bitmap, frame_count)
frame_width = baseSprite.bitmap.width / frame_count # Calculate frame width
frame_count.times do |i|
# Calculate offset for each frame
frame_offset = [i * frame_width, 0]
# Adjust Y offset if frame index is odd
frame_offset[1] -= 2 if i.odd?
positionHat(baseBitmap, hat_frame_bitmap, frame_offset, i, frame_width)
end
end
return baseBitmap
end
#for continue screen
def generateClothedBitmapStatic(trainer, action = "walk")
baseBitmapFilename = getBaseOverworldSpriteFilename(action, trainer.skin_tone)
if !pbResolveBitmap(baseBitmapFilename)
baseBitmapFilename = Settings::PLAYER_GRAPHICS_FOLDER + action
end
baseSprite = AnimatedBitmap.new(baseBitmapFilename)
# Clone the base sprite bitmap to create the base for the player's sprite
baseBitmap = baseSprite.bitmap.clone # nekkid sprite
outfitFilename = getOverworldOutfitFilename(trainer.clothes, action)
outfitFilename = getOverworldOutfitFilename(Settings::PLAYER_TEMP_OUTFIT_FALLBACK) if !pbResolveBitmap(outfitFilename)
hairFilename = getOverworldHairFilename(trainer.hair)
hatFilename = getOverworldHatFilename(trainer.hat)
hat2Filename = getOverworldHatFilename(trainer.hat2)
# Use default values if color shifts are not set
hair_color_shift = trainer.hair_color || 0
hat_color_shift = trainer.hat_color || 0
hat2_color_shift = trainer.hat2_color || 0
clothes_color_shift = trainer.clothes_color || 0
# Use fallback outfit if the specified outfit cannot be resolved
if !pbResolveBitmap(outfitFilename)
outfitFilename = Settings::PLAYER_TEMP_OUTFIT_FALLBACK
end
# Load the outfit and hair bitmaps
outfitBitmap = AnimatedBitmap.new(outfitFilename, clothes_color_shift)
hairBitmapWrapper = AnimatedBitmap.new(hairFilename, hair_color_shift) if pbResolveBitmap(hairFilename)
hatBitmapWrapper = AnimatedBitmap.new(hatFilename, hat_color_shift) if pbResolveBitmap(hatFilename)
hat2BitmapWrapper = AnimatedBitmap.new(hat2Filename, hat2_color_shift) if pbResolveBitmap(hat2Filename)
# Blit the outfit onto the base sprite
baseBitmap.blt(0, 0, outfitBitmap.bitmap, outfitBitmap.bitmap.rect) if outfitBitmap
current_offset = [0, 0] # Replace this with getCurrentSpriteOffset() if needed
positionHair(baseBitmap, hairBitmapWrapper.bitmap, current_offset) if hairBitmapWrapper
frame_count = 4
frame_width = baseSprite.bitmap.width / frame_count # Calculate frame width
if hat2BitmapWrapper
hat2_frame_bitmap = duplicateHatForFrames(hat2BitmapWrapper.bitmap, frame_count)
frame_count.times do |i|
# Calculate offset for each frame
frame_offset = [i * frame_width, 0]
# Adjust Y offset if frame index is odd
frame_offset[1] -= 2 if i.odd?
positionHat(baseBitmap, hat2_frame_bitmap, frame_offset, i, frame_width)
end
end
if hatBitmapWrapper
hat_frame_bitmap = duplicateHatForFrames(hatBitmapWrapper.bitmap, frame_count)
frame_count.times do |i|
# Calculate offset for each frame
frame_offset = [i * frame_width, 0]
# Adjust Y offset if frame index is odd
frame_offset[1] -= 2 if i.odd?
positionHat(baseBitmap, hat_frame_bitmap, frame_offset, i, frame_width)
end
end
return baseBitmap
end
def positionHair(baseBitmap, hairBitmap, offset)
baseBitmap.blt(offset[0], offset[1], hairBitmap, hairBitmap.rect)
end
def positionHat(baseBitmap, hatBitmap, offset, frame_index, frame_width)
# Define a rect for each frame
frame_rect = Rect.new(frame_index * frame_width, 0, frame_width, hatBitmap.height)
# Blit only the part of the hat corresponding to the current frame
baseBitmap.blt(offset[0], offset[1], hatBitmap, frame_rect)
end
def duplicateHatForFrames(hatBitmap, frame_count)
# Create a new bitmap for the duplicated hat frames
frame_width = hatBitmap.width
total_width = frame_width * frame_count
duplicatedBitmap = Bitmap.new(total_width, hatBitmap.height)
# Copy the single hat frame across each required frame
frame_count.times do |i|
duplicatedBitmap.blt(i * frame_width, 0, hatBitmap, hatBitmap.rect)
end
return duplicatedBitmap
end
def add_hat_to_bitmap(bitmap, hat_id, x_pos, y_pos, scale = 1, mirrored = false)
base_scale = 1.5 #coz hat & poke sprites aren't the same size
adjusted_scale = base_scale * scale
hat_filename = getTrainerSpriteHatFilename(hat_id)
hatBitmapWrapper = AnimatedBitmap.new(hat_filename, 0) if pbResolveBitmap(hat_filename)
hatBitmapWrapper.scale_bitmap(adjusted_scale) if hatBitmapWrapper
hatBitmapWrapper.mirror if hatBitmapWrapper && mirrored
bitmap.blt(x_pos * adjusted_scale, y_pos * adjusted_scale, hatBitmapWrapper.bitmap, hatBitmapWrapper.bitmap.rect) if hatBitmapWrapper
end
class PokemonTemp
attr_accessor :trainer_preview
end
def display_outfit_preview(x = 320, y = 0, withBorder = true)
hide_outfit_preview() if $PokemonTemp.trainer_preview
$PokemonTemp.trainer_preview = TrainerClothesPreview.new(x, y, withBorder)
$PokemonTemp.trainer_preview.show()
end
def hide_outfit_preview()
$game_screen.pictures[20].erase
$PokemonTemp.trainer_preview.erase() if $PokemonTemp.trainer_preview
$PokemonTemp.trainer_preview = nil
end

View File

@@ -0,0 +1,174 @@
class OutfitSelector
attr_reader :clothes_list
attr_reader :hats_list
attr_reader :hairstyles_list
def initialize()
@clothes_list = parse_clothes_folder()
@hats_list = parse_hats_folder()
@hairstyles_list =parse_hairstyles_folder()
end
def parse_clothes_folder
return list_folders(get_clothes_sets_list_path())
end
def parse_hats_folder
return list_folders(get_hats_sets_list_path())
end
def parse_hairstyle_types_folder
return list_folders(get_hair_sets_list_path())
end
def generate_hats_choice(baseOptions=true,additionalIds=[],additionalTags=[],filterOutTags=[])
list = []
list += additionalIds
list += search_hats(additionalTags)
if baseOptions
list += get_hats_base_options()
list += search_hats(get_regional_sets_tags())
end
return list
end
def generate_clothes_choice(baseOptions=true,additionalIds=[],additionalTags=[],filterOutTags=[])
list = []
list += additionalIds
list += search_clothes(additionalTags)
if baseOptions
list += get_clothes_base_options()
list += search_clothes(get_regional_sets_tags())
end
return list
end
def generate_hairstyle_choice(baseOptions=true,additionalIds=[],additionalTags=[],filterOutTags=[])
list = []
list += additionalIds
list += search_hairstyles(additionalTags)
if baseOptions
list += get_hairstyle_salon_base_options()
list += search_hairstyles(get_regional_sets_tags())
end
list << HAIR_BALD
return list
end
def get_regional_sets_tags()
regional_tags = []
regional_tags << "kanto" if $game_switches[SWITCH_KANTO_HAIR_COLLECTION]
regional_tags << "johto" if $game_switches[SWITCH_JOHTO_HAIR_COLLECTION]
regional_tags << "hoenn" if $game_switches[SWITCH_HOENN_HAIR_COLLECTION]
regional_tags << "sinnoh" if $game_switches[SWITCH_SINNOH_HAIR_COLLECTION]
regional_tags << "unova" if $game_switches[SWITCH_UNOVA_HAIR_COLLECTION]
regional_tags << "kalos" if $game_switches[SWITCH_KALOS_HAIR_COLLECTION]
regional_tags << "alola" if $game_switches[SWITCH_ALOLA_HAIR_COLLECTION]
regional_tags << "galar" if $game_switches[SWITCH_GALAR_HAIR_COLLECTION]
regional_tags << "paldea" if $game_switches[SWITCH_PALDEA_HAIR_COLLECTION]
return regional_tags
end
def get_hairstyle_salon_base_options()
return search_hairstyles(["default"])
end
def get_clothes_base_options()
return search_clothes(["default"])
end
def get_hats_base_options()
return search_hats(["default"])
end
def parse_hairstyles_folder
hairstyle_types= list_folders(get_hair_sets_list_path())
max_versions_number = 10
list= []
for hairstyle in hairstyle_types
for i in 1..max_versions_number
type = i.to_s + "_" + hairstyle
filePath = getOverworldHairFilename(type)
if pbResolveBitmap(filePath)
list << type
end
end
end
return list
end
def list_folders(path)
entries= Dir.entries(path)
return entries.select { |entry| File.directory?(File.join(path, entry)) && entry != '.' && entry != '..' }
end
def filter_unlocked_outfits(outfits_list,unlocked_outfits)
available_outfits = []
outfits_list.each do |outfit|
available_outfits << outfit if unlocked_outfits.include?(outfit)
end
return available_outfits
end
def selectNextOutfit(currentOutfit, incr, outfits_list, versions = [], allowNone = true, prefix_filter = nil,unlockedOutfits=[],everythingUnlocked=false)
available_outfits = []
available_outfits = outfits_list if everythingUnlocked
available_outfits << "" if allowNone
available_outfits += filter_unlocked_outfits(outfits_list,unlockedOutfits) if !everythingUnlocked
#available_outfits += list_available_outfits(directory, versions, unlockedOutfits, prefix_filter) #unlockedOutfits = nil for all outfits unlocked
last_outfit = available_outfits[-1]
current_outfit_index = get_current_outfit_position(currentOutfit, available_outfits)
next_outfit_index = current_outfit_index +incr
nextOutfit = available_outfits[next_outfit_index]
nextOutfit = last_outfit if next_outfit_index < 0
nextOutfit = available_outfits[0] if next_outfit_index >= available_outfits.length()
return nextOutfit if available_outfits.include?(nextOutfit)
return currentOutfit
end
def changeToNextClothes(incr,all_unlocked=false)
$Trainer.unlocked_clothes = [] if !$Trainer.unlocked_clothes
currentOutfit = $Trainer.clothes
currentOutfit = 0 if !currentOutfit
nextOutfit = selectNextOutfit(currentOutfit, incr, @clothes_list, [], false,nil,$Trainer.unlocked_clothes,all_unlocked)
$Trainer.clothes = nextOutfit
$Trainer.clothes_color = 0
echoln $Trainer.clothes
end
def changeToNextHat(incr,all_unlocked=false)
$Trainer.unlocked_hats = [] if !$Trainer.unlocked_hats
currentHat = $Trainer.hat
currentHat = 0 if !currentHat
nextOutfit = selectNextOutfit(currentHat, incr, @hats_list, [], true, "hat",$Trainer.unlocked_hats,all_unlocked)
$Trainer.hat = nextOutfit
$Trainer.hat_color = 0
echoln $Trainer.hat
end
def changeToNextHairstyle(incr,all_unlocked=false)
$Trainer.unlocked_hairstyles = [] if !$Trainer.unlocked_hairstyles
currentHair = $Trainer.hair
currentHair = 0 if !currentHair
nextOutfit = selectNextOutfit(currentHair, incr, @hairstyles_list, ["a", "b", "c", "d"], true,nil,$Trainer.unlocked_hairstyles,all_unlocked)
$Trainer.hair_color = 0
$Trainer.hair = nextOutfit
echoln $Trainer.hair
end
end

View File

@@ -0,0 +1,75 @@
class PokemonGlobalMetadata
attr_accessor :hats_data
attr_accessor :hairstyles_data
attr_accessor :clothes_data
end
def update_global_hats_list()
file_path = Settings::HATS_DATA_PATH
json_data = File.read(file_path)
hat_data = HTTPLite::JSON.parse(json_data)
$PokemonGlobal.hats_data = {}
# Iterate through the JSON data and create Hat objects
hat_data.each do |data|
tags = data['tags'] ? data['tags'].split(',').map(&:strip) : []
hat = Hat.new(
data['id'],
data['name'],
data['description'],
data['price'],
tags
)
$PokemonGlobal.hats_data[hat.id] = hat
end
end
def update_global_hairstyles_list()
file_path = Settings::HAIRSTYLE_DATA_PATH
json_data = File.read(file_path)
hair_data = HTTPLite::JSON.parse(json_data)
$PokemonGlobal.hairstyles_data = {}
# Iterate through the JSON data and create Hat objects
hair_data.each do |data|
tags = data['tags'] ? data['tags'].split(',').map(&:strip) : []
hair = Hairstyle.new(
data['id'],
data['name'],
data['description'],
data['price'],
tags
)
$PokemonGlobal.hairstyles_data[hair.id] = hair
end
end
def update_global_clothes_list()
file_path = Settings::CLOTHES_DATA_PATH
json_data = File.read(file_path)
outfits_data = HTTPLite::JSON.parse(json_data)
$PokemonGlobal.clothes_data = {}
# Iterate through the JSON data and create Hat objects
outfits_data.each do |data|
tags = data['tags'] ? data['tags'].split(',').map(&:strip) : []
outfit = Clothes.new(
data['id'],
data['name'],
data['description'],
data['price'],
tags
)
$PokemonGlobal.clothes_data[outfit.id] = outfit
end
end
def update_global_outfit_lists()
update_global_hats_list
update_global_hairstyles_list
update_global_clothes_list
end

View File

@@ -0,0 +1,221 @@
#CLOTHES
def search_clothes(matching_tags = [], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.clothes_data
existing_files_list = selector.parse_clothes_folder()
unlocked_list = $Trainer.unlocked_clothes
return search_outfits_by_tag(full_data_list, matching_tags, existing_files_list, unlocked_list, only_unlocked)
end
def filter_clothes(filter_tags = [], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.hats_data
existing_files_list = selector.parse_hats_folder()
unlocked_list = $Trainer.unlocked_hats
return filter_outfits_by_tag(full_data_list, filter_tags, existing_files_list, unlocked_list, only_unlocked)
end
def filter_clothes_only_not_owned(clothes_ids_list)
filtered_list = []
clothes_ids_list.each do|clothe_id|
filtered_list << clothe_id if !$Trainer.unlocked_clothes.include?(clothe_id)
end
return filtered_list
end
def filter_clothes_only_owned(clothes_ids_list)
filtered_list = []
clothes_ids_list.each do|clothe_id|
filtered_list << clothe_id if $Trainer.unlocked_clothes.include?(clothe_id)
end
return filtered_list
end
#HATS
def search_hats(matching_tags = [],excluding_tags=[], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.hats_data
existing_files_list = selector.parse_hats_folder()
unlocked_list = $Trainer.unlocked_hats
return search_outfits_by_tag(full_data_list, matching_tags, existing_files_list, unlocked_list, only_unlocked,excluding_tags)
end
def filter_hats(filter_tags = [], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.hats_data
existing_files_list = selector.parse_hats_folder()
unlocked_list = $Trainer.unlocked_hats
return filter_outfits_by_tag(full_data_list, filter_tags, existing_files_list, unlocked_list, only_unlocked)
end
def filter_hats_only_not_owned(hats_ids_list)
filtered_list = []
hats_ids_list.each do|hat_id|
filtered_list << hat_id if !$Trainer.unlocked_hats.include?(hat_id)
end
return filtered_list
end
def filter_hats_only_owned(hats_ids_list)
filtered_list = []
hats_ids_list.each do|hat_id|
filtered_list << hat_id if $Trainer.unlocked_hats.include?(hat_id)
end
return filtered_list
end
#HAIRSTYLES
def search_hairstyles(matching_tags = [], only_unlocked = false)
update_global_outfit_lists()
selector = OutfitSelector.new
full_data_list = $PokemonGlobal.hairstyles_data
existing_files_list = selector.parse_hairstyle_types_folder()
return search_outfits_by_tag(full_data_list, matching_tags, existing_files_list, [], false)
end
def filter_out_hairstyles(filter_tags = [],base_list = [],require_unlocked=false)
update_global_outfit_lists()
selector = OutfitSelector.new
data_list = $PokemonGlobal.hairstyles_data
existing_files_list = selector.parse_hairstyle_types_folder()
return exclude_outfits_by_tag(data_list, filter_tags, existing_files_list, base_list, false)
end
# Generic searching methods
#Get outfits that have ANY of the tags
def search_outfits_by_tag(outfits_map, matching_tags = [], physical_files_list = [], unlocked_list = [], require_unlocked = false, excluding_tags=[])
filtered_list = []
outfits_map.each do |outfit_id, outfit|
next if outfit.tags.any? { |tag| excluding_tags.include?(tag) }
if outfit.tags.any? { |tag| matching_tags.include?(tag) }
filtered_list << outfit_id if outfit_is_valid?(outfit_id, physical_files_list, unlocked_list, require_unlocked)
end
end
return filtered_list
end
#Get outfits that have ALL of the tags
def filter_outfits_by_tag(outfits_map, filter_tags = [], physical_files_list = [], unlocked_list = [], require_unlocked = false)
update_global_outfit_lists()
filtered_list = []
outfits_map.each do |outfit_id, outfit|
if filter_tags.all? { |tag| outfit.tags.include?(tag) }
filtered_list << outfit_id if outfit_is_valid?(outfit_id, physical_files_list, unlocked_list, require_unlocked)
end
end
return filtered_list
end
#Get all outfits from list that DON'T have a tag
def exclude_outfits_by_tag(outfits_map, filter_tags = [], physical_files_list = [], unlocked_list = [], require_unlocked = false)
update_global_outfit_lists()
filtered_list = []
outfits_map.each do |outfit_id, outfit|
if filter_tags.any? { |tag| !outfit.tags.include?(tag) }
filtered_list << outfit_id if outfit_is_valid?(outfit_id, physical_files_list, unlocked_list, require_unlocked)
end
end
return filtered_list
end
def outfit_is_valid?(outfit_id, physical_files_list, unlocked_list, require_unlocked)
return false if require_unlocked && !unlocked_list.include?(outfit_id)
return physical_files_list.include?(outfit_id)
end
def add_tags(tags_list=[])
newTag=pbEnterText("add tag",0,10)
return tags_list if newTag.length == 0
tags_list << newTag
return tags_list
end
def get_clothes_by_id(id)
update_global_outfit_lists()
return $PokemonGlobal.clothes_data.has_key?(id) ? $PokemonGlobal.clothes_data[id] : nil
end
def get_hat_by_id(id)
update_global_outfit_lists()
return $PokemonGlobal.hats_data.has_key?(id) ? $PokemonGlobal.hats_data[id] : nil
end
def get_hair_by_id(id)
update_global_outfit_lists()
return $PokemonGlobal.hairstyles_data.has_key?(id) ? $PokemonGlobal.hairstyles_data[id] : nil
end
def generate_clothes_choice(baseOptions=true,additionalIds=[],additionalTags=[],filterOutTags=[])
list = []
list += additionalIds
list += search_clothes(additionalTags)
if baseOptions
list += get_clothes_base_options()
list += search_clothes(get_regional_sets_tags())
end
return list
end
CITY_OUTFIT_TAGS= [
"pewter","cerulean","vermillion","lavender","celadon","fuchsia","cinnabar",
"crimson","goldenrod","azalea", "violet", "blackthorn", "mahogany", "ecruteak",
"olivine","cianwood", "kin"
]
def list_city_exclusive_clothes()
tags_list = CITY_OUTFIT_TAGS
echoln search_clothes(tags_list)
return search_clothes(tags_list)
end
def list_city_exclusive_hats()
tags_list = CITY_OUTFIT_TAGS
return search_hats(tags_list)
end
def list_city_exclusive_hairstyles()
tags_list = CITY_OUTFIT_TAGS
return search_hairstyles(tags_list)
end
def list_regional_clothes()
selector = OutfitSelector.new
tags_list = selector.get_regional_sets_tags()
return search_clothes(tags_list)
end
def list_regional_hats()
selector = OutfitSelector.new
tags_list = selector.get_regional_sets_tags()
return search_hats(tags_list)
end
def list_regional_hairstyles()
selector = OutfitSelector.new
tags_list = selector.get_regional_sets_tags()
return search_hairstyles(tags_list)
end

View File

@@ -0,0 +1,185 @@
#set outfit ids,
#
CLOTHES_NORMAL = "normal"
CLOTHES_FIGHTING = "fighting"
CLOTHES_FLYING = "temp"
CLOTHES_POISON = "deadlypoisondanger"
CLOTHES_GROUND = "groundcowboy"
CLOTHES_ROCK = "temp"
CLOTHES_BUG_1 = "bughakama"
CLOTHES_BUG_2 = "bughakamapants"
CLOTHES_GHOST = "temp"
CLOTHES_STEEL_M = "steelworkerM"
CLOTHES_STEEL_F = "steelworkerF"
CLOTHES_FIRE = "fire"
CLOTHES_WATER = "waterdress"
CLOTHES_GRASS = "temp"
CLOTHES_ELECTRIC = "urbanelectric"
CLOTHES_PSYCHIC = "temp"
CLOTHES_ICE = "iceoutfit"
CLOTHES_DRAGON = "dragonconqueror"
CLOTHES_DARK = "temp"
CLOTHES_FAIRY_M = "mikufairym"
CLOTHES_FAIRY_F = "mikufairyf"
NORMAL_ITEMS = [:NORMALGEM,:MOOMOOMILK,:POTION,:FULLHEAL,:CHILANBERRY,]
FIGHTING_ITEMS = [:FIGHTINGGEM,:PROTEIN,:CHOPLEBERRY,]
FLYING_ITEMS = [:FLYINGGEM,:HEALTHWING,:MUSCLEWING,:RESISTWING,:GENIUSWING,:CLEVERWING,:SWIFTWING,:AIRBALLOON,:PRETTYWING,:COBABERRY, ]
POISON_ITEMS = [:POISONGEM,:ANTIDOTE, :KEBIABERRY, ]
GROUND_ITEMS = [:GROUNDGEM,:SHUCABERRY, ]
ROCK_ITEMS = [:ROCKGEM, :STARDUST,:CHARTIBERRY, ]
BUG_ITEMS = [:BUGGEM,:HONEY,:TANGABERRY, ]
GHOST_ITEMS = [:GHOSTGEM,:KASIBBERRY,]
STEEL_ITEMS = [:STEELGEM,:BABIRIBERRY,:METALPOWDER,]
FIRE_ITEMS = [:FIREGEM,:LAVACOOKIE,:BURNHEAL,:OCCABERRY, ]
WATER_ITEMS = [:WATERGEM,:HEARTSCALE,:PEARL,:PASSHOBERRY ]
GRASS_ITEMS = [:GRASSGEM,:LUMBERRY,:ORANBERRY,:SITRUSBERRY,:GRASSYSEED,:ABSORBBULB,:TINYMUSHROOM, :RINDOBERRY, ]
ELECTRIC_ITEMS = [:ELECTRICGEM,:ELECTRICSEED,:PARLYZHEAL,:CELLBATTERY,:WACANBERRY, ]
PSYCHIC_ITEMS = [:PSYCHICGEM,:PSYCHICSEED, :MENTALHERB, :PAYAPABERRY,]
ICE_ITEMS = [:ICEGEM,:SNOWBALL,:ICEHEAL,:YACHEBERRY, ]
DRAGON_ITEMS = [:DRAGONGEM,:HABANBERRY, ]
DARK_ITEMS = [:DARKGEM,:COLBURBERRY, ]
FAIRY_ITEMS = [:FAIRYGEM,:MISTYSEED, ]
def isWearingElectricOutfit()
return (isWearingClothes(CLOTHES_ELECTRIC))
end
def isWearingNormalOutfit()
return (isWearingClothes(CLOTHES_NORMAL))
end
def isWearingFightingOutfit()
return (isWearingClothes(CLOTHES_FIGHTING))
end
def isWearingFlyingOutfit()
return (isWearingClothes(CLOTHES_FLYING))
end
def isWearingPoisonOutfit()
return (isWearingClothes(CLOTHES_POISON))
end
def isWearingGroundOutfit()
return (isWearingClothes(CLOTHES_GROUND))
end
def isWearingRockOutfit()
return (isWearingClothes(CLOTHES_ROCK))
end
def isWearingBugOutfit()
return ((isWearingClothes(CLOTHES_BUG_1) || isWearingClothes(CLOTHES_BUG_2)))
end
def isWearingGhostOutfit()
return (isWearingClothes(CLOTHES_GHOST))
end
def isWearingSteelOutfit()
return ((isWearingClothes(CLOTHES_STEEL_M) || isWearingClothes(CLOTHES_STEEL_F)))
end
def isWearingFireOutfit()
return (isWearingClothes(CLOTHES_FIRE))
end
def isWearingWaterOutfit()
return (isWearingClothes(CLOTHES_WATER))
end
def isWearingGrassOutfit()
return (isWearingClothes(CLOTHES_GRASS))
end
def isWearingPsychicOutfit()
return (isWearingClothes(CLOTHES_PSYCHIC))
end
def isWearingIceOutfit()
return (isWearingClothes(CLOTHES_ICE))
end
def isWearingDragonOutfit()
return (isWearingClothes(CLOTHES_DRAGON))
end
def isWearingDarkOutfit()
return (isWearingClothes(CLOTHES_DARK))
end
def isWearingFairyOutfit()
return ((isWearingClothes(CLOTHES_FAIRY_M) || isWearingClothes(CLOTHES_FAIRY_F)))
end
def pickUpTypeItemSetBonus()
return if rand(10) != 0
items_list = if isWearingElectricOutfit()
ELECTRIC_ITEMS
elsif isWearingNormalOutfit()
NORMAL_ITEMS
elsif isWearingFightingOutfit()
FIGHTING_ITEMS
elsif isWearingFlyingOutfit()
FLYING_ITEMS
elsif isWearingPoisonOutfit()
POISON_ITEMS
elsif isWearingGroundOutfit()
GROUND_ITEMS
elsif isWearingRockOutfit()
ROCK_ITEMS
elsif isWearingBugOutfit()
BUG_ITEMS
elsif isWearingGhostOutfit()
GHOST_ITEMS
elsif isWearingSteelOutfit()
STEEL_ITEMS
elsif isWearingFireOutfit()
FIRE_ITEMS
elsif isWearingWaterOutfit()
WATER_ITEMS
elsif isWearingGrassOutfit()
GRASS_ITEMS
elsif isWearingPsychicOutfit()
PSYCHIC_ITEMS
elsif isWearingIceOutfit()
ICE_ITEMS
elsif isWearingDragonOutfit()
DRAGON_ITEMS
elsif isWearingDarkOutfit()
DARK_ITEMS
elsif isWearingFairyOutfit()
FAIRY_ITEMS
else
[]
end
if !items_list.empty?
Kernel.pbItemBall(items_list.sample)
end
end

View File

@@ -0,0 +1,148 @@
#Clothes
CLOTHES_TEAM_ROCKET_MALE = "rocketm"
CLOTHES_TEAM_ROCKET_FEMALE = "rocketf"
CLOTHES_OFFICE_WORKER_F = "officeworkerf"
CLOTHES_OFFICE_WORKER_M = "officeworkerm"
CLOTHES_BUSINESS_SUIT = "BusinessSuit"
CLOTHES_ADVENTURER = "fantasyadventurersoutfit"
CLOTHES_EMERALD = "emeraldSPE"
CLOTHES_PIKACHU_ONESIE = "pikaonesie"
CLOTHES_GLITCH = "glitzerset"
CLOTHES_BREEDER="PKMBreeder"
CLOTHES_FOSSIL_M ="sado"
CLOTHES_FOSSIL_F ="sada"
CLOTHES_TREVENANT= "trevenantforestkingcloak"
CLOTHES_WAITRESS = "maid"
CLOTHES_WAITER = "butler"
CLOTHES_LASS_YELLOW ="lass"
CLOTHES_LASS_BLUE ="lass2"
DEFAULT_OUTFIT_MALE = "red"
DEFAULT_OUTFIT_FEMALE = "leaf"
STARTING_OUTFIT = "pikajamas"
#Hats
HAT_TEAM_ROCKET = "rocketcap"
HAT_POSTMAN = "postman"
HAT_PIDGEY_NEST = "pidgey"
HAT_SWABLU_NEST = "swablu"
HAT_PIKACHUM_NEST = "pikhatchum"
HAT_PIKACHUF_NEST = "pikhatchuf"
HAT_PARAS_NEST = "headparas"
HAT_EEVEE_NEST = "eevee"
HAT_PARASHROOM = "parashroom"
HAT_AERODACTYL = "aerodactylSkull"
HAT_DUSKULL_MASK = "duskullmask"
HAT_SLEEPMASK = "sleepmask"
HAT_DITTO_MASK = "creepydittomask"
HAT_EGG = "egg"
HAT_DRIFLOON_CAP = "drifloon"
HAT_EMERALD = "emeraldSPEgem"
HAT_SQUIRTLE_SHADES = "squirtlesquadshades"
HAT_WOOPER = "wooperclips"
HAT_PIKACHU_HOOD = "pikaonesie"
HAT_FEZ = "fez"
HAT_HALO = "halo"
HAT_MAGIKARP = "magicap"
HAT_SLOWKING_SHELL = "slowking"
HAT_ZOROARK = "banefulfoxmask"
HAT_FROG = "froghat"
HAT_SANTA = "santa"
HAT_QMARKS = "glitzerset"
HAT_SUDOWOODO = "sudowoodohorns"
HAT_TREVENANT="trevenantforestkingcrown"
HAT_CLOWN = "clownnose"
HAT_BREEDER_1="breedervisor"
HAT_BREEDER_2="breederbandana"
HAT_BREEDER_2_2="PKMBreeder"
HAT_BREEDER_3="egg"
HAT_BREEDEROUTFIT="PKMBreeder"
HAT_WAITRESS = "maid"
FUSION_HAT = "fusionnerd"
FUSION_OUTFIT = "fusionnerd"
HAT_ASH = "ash"
HAT_BIANCA = "bianca"
HAT_CLEFAIRY = "clefairyearheadband"
HAT_FLOWER = "mikufairy"
HAT_SKITTY_TV = "skittyTV"
HAT_TVHEAD = "tvhead"
HAT_SCRIBBLES1 = "scribbles1"
HAT_SCRIBBLES2 = "scribbles2"
HAT_SCRIBBLES3 = "scribbles3"
HAT_SCRIBBLES4 = "scribbles4"
HAT_CARDBOARD_BOX = "box"
HAT_CAPTAIN = "seacaptain"
HAT_GYM_REWARD_1 = "brockpan"
HAT_GYM_REWARD_2 = "starmieclip"
HAT_GYM_REWARD_3 = "surgeglasses"
HAT_GYM_REWARD_4 = "erikaHeadband"
HAT_GYM_REWARD_5 = "kogascarf"
HAT_GYM_REWARD_6 = "sabrinasballs"
HAT_GYM_REWARD_7 = "blaineGlasses"
HAT_GYM_REWARD_8 = "giovannifedora"
HAT_GYM_REWARD_9 = "luluribbon"
HAT_GYM_REWARD_10 = "kurtsentaihelmet"
HAT_GYM_REWARD_11 = "falknerscage"
HAT_GYM_REWARD_12 = "clairbow"
HAT_GYM_REWARD_13 = "chuckmoustache"
HAT_GYM_REWARD_14 = "prycemask"
HAT_GYM_REWARD_15 = "mortyHeadband"
HAT_GYM_REWARD_16 = "magnemitepin"
#Hairstyles
HAIR_RED = "red"
HAIR_LEAF = "leaf"
HAIR_HEXMANIAC = "HexManiac"
HAIR_LASS = "lass"
HAIR_BALD = "bald"
HAIR_RIVAL = "gary"
HAIR_BROCK = "brock"
HAIR_MISTY1 = "mistyRBY"
HAIR_MISTY2 = "mistyGSC"
HAIR_SURGE = "surge" #does not exist yet
HAIR_ERIKA = "erika"
HAIR_KOGA = "koga" #does not exist yet
HAIR_JANINE = "janine"
HAIR_SABRINA = "sabrinaGSC"
HAIR_BLAINE = "blaine" #does not exist yet
HAIR_GIOVANNI = "giovanni" #does not exist yet
HAIR_WHITNEY = "whitney"
HAIR_KURT = "kurt"
HAIR_FALKNER = "falkner"
HAIR_CLAIR = "clair"
HAIR_CHUCK = "chuck" #does not exist yet
HAIR_PRYCE = "pryce" #does not exist yet
HAIR_MORTY = "morty" #does not exist yet
HAIR_JASMINE = "jasmine" #does not exist yet
HAIR_HOOH = "ho-oh"
HAIR_CRESSELIA = "lunarbob"
HAIR_LYCANROC="lycanrocshorthair"
HAIR_HAPPINY="happinysuit"
HAIR_LATIAS="SpecialLatias"
HAIR_GARDEVOIR="gardevoir"
HAIR_EEVEE="eeveetail"

View File

@@ -0,0 +1,181 @@
class CharacterSelectionMenuView
attr_accessor :name_sprite
attr_accessor :viewport
attr_accessor :sprites
attr_accessor :textValues
OPTIONS_START_Y = 66
CURSOR_Y_MARGIN = 50
CURSOR_X_MARGIN = 76
CHECKMARK_Y_MARGIN = 20
CHECKMARK_WIDTH = 50
OPTIONS_LABEL_X = 50
OPTIONS_LABEL_WIDTH = 100
OPTIONS_VALUE_X = 194
SELECTOR_X = 120
SELECTOR_STAGGER_OFFSET=26
ARROW_LEFT_X_POSITION = 75
ARROW_RIGHT_X_POSITION = 275
ARROWS_Y_OFFSET = 10#20
CONFIRM_X = 296
CONFIRM_Y= 322
STAGGER_OFFSET_1 = 26
STAGGER_OFFSET_2 = 50
def initialize
@presenter = CharacterSelectMenuPresenter.new(self)
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@sprites = {}
@textValues={}
@max_index=5
end
def init_graphics()
@sprites["bg"] = IconSprite.new(@viewport)
@sprites["bg"].setBitmap("Graphics/Pictures/trainer_application_form")
@sprites["select"] = IconSprite.new(@viewport)
@sprites["select"].setBitmap("Graphics/Pictures/cc_selection_box")
@sprites["select"].x = get_cursor_x_position(0)#OPTIONS_LABEL_X + OPTIONS_LABEL_WIDTH + CURSOR_X_MARGIN
@sprites["select"].y = OPTIONS_START_Y
@sprites["select"].visible = true
@sprites["leftarrow"] = AnimatedSprite.new("Graphics/Pictures/leftarrow", 8, 40, 28, 2, @viewport)
@sprites["leftarrow"].x = ARROW_LEFT_X_POSITION
@sprites["leftarrow"].y = 0
@sprites["leftarrow"].visible = false
@sprites["leftarrow"].play
@sprites["rightarrow"] = AnimatedSprite.new("Graphics/Pictures/rightarrow", 8, 40, 28, 2, @viewport)
@sprites["rightarrow"].x = ARROW_RIGHT_X_POSITION
@sprites["rightarrow"].y = 0
@sprites["rightarrow"].visible = false
@sprites["rightarrow"].play
@presenter.setInitialValues()
end
def setMaxIndex(maxIndex)
@max_index=maxIndex
end
def init_labels()
Kernel.pbDisplayText("Confirm", (CONFIRM_X+CURSOR_X_MARGIN), CONFIRM_Y)
#Labels are directly in the image
# current_Y = OPTIONS_START_Y
# for option in @presenter.options
# x_pos = option == "Confirm" ? OPTIONS_VALUE_X : OPTIONS_LABEL_X
#
# Kernel.pbDisplayText(option, x_pos, current_Y)
# current_Y += CURSOR_Y_MARGIN
# end
end
def start
init_graphics()
init_labels()
@presenter.main()
end
def get_cursor_y_position(index)
return CONFIRM_Y if index == @max_index
return index * CURSOR_Y_MARGIN + OPTIONS_START_Y
end
def get_cursor_x_position(index)
return CONFIRM_X if index == @max_index
return SELECTOR_X + getTextBoxStaggerOffset(index)
end
def get_value_x_position(index)
return (OPTIONS_VALUE_X + getTextBoxStaggerOffset(index))
end
def getTextBoxStaggerOffset(index)
case index
when 1
return STAGGER_OFFSET_1
when 2
return STAGGER_OFFSET_2
when 3
return STAGGER_OFFSET_1
end
return 0
end
def showSideArrows(y_index)
y_position = get_cursor_y_position(y_index)
@sprites["rightarrow"].y=y_position+ARROWS_Y_OFFSET
@sprites["leftarrow"].y=y_position+ARROWS_Y_OFFSET
@sprites["leftarrow"].x=getTextBoxStaggerOffset(y_index)+ARROW_LEFT_X_POSITION
@sprites["rightarrow"].x= getTextBoxStaggerOffset(y_index)+ARROW_RIGHT_X_POSITION
@sprites["rightarrow"].visible=true
@sprites["leftarrow"].visible=true
end
def hideSideArrows()
@sprites["rightarrow"].visible=false
@sprites["leftarrow"].visible=false
end
def displayAge(age,y_index)
y_position = get_cursor_y_position(y_index)
x_position = get_value_x_position(y_index)
Kernel.pbClearNumber()
Kernel.pbDisplayNumber(age,x_position,y_position)
end
def displayText(spriteId,text,y_index)
@textValues[spriteId].dispose if @textValues[spriteId]
yposition = get_cursor_y_position(y_index)
xposition = get_value_x_position(y_index)
baseColor= baseColor ? baseColor : Color.new(72,72,72)
shadowColor= shadowColor ? shadowColor : Color.new(160,160,160)
@textValues[spriteId] = BitmapSprite.new(Graphics.width,Graphics.height,@viewport)
text1=_INTL(text)
textPosition=[
[text1,xposition,yposition,2,baseColor,shadowColor],
]
pbSetSystemFont(@textValues[spriteId].bitmap)
pbDrawTextPositions(@textValues[spriteId].bitmap,textPosition)
end
def updateGraphics()
Graphics.update
Input.update
if @sprites
@sprites["rightarrow"].update
@sprites["leftarrow"].update
end
end
end

View File

@@ -0,0 +1,275 @@
class CharacterSelectMenuPresenter
attr_accessor :options
attr_reader :current_index
OPTION_NAME = 'Name'
OPTION_AGE = "Age"
OPTION_GENDER = "Gender"
OPTION_HAIR = "Hair"
OPTION_SKIN = "Skin"
OPTION_CONFIRM = "Confirm"
MIN_AGE = 10
MAX_AGE = 17
DEFAULT_NAMES = ["Green", "Red"]
MIN_SKIN_COLOR = 1
MAX_SKIN_COLOR = 6
SKIN_COLOR_IDS = ["Type A", "Type B", "Type C", "Type D", "Type E", "Type F"]
GENDERS_IDS = ["Female", "Male"]
HAIR_COLOR_IDS = [1, 2, 3, 4]
HAIR_COLOR_NAMES = ["Blonde", "Light Brown", "Dark Brown", "Black"]
#ids for displayed text sprites
NAME_TEXT_ID = "name"
HAIR_TEXT_ID = "hair"
SKIN_TEXT_ID = "skin"
def initialize(view)
@view = view
@gender = 1
@age = MIN_AGE
@name = ""
@skinTone = 5
@hairstyle = "red"
@hairColor = 2
@options = [OPTION_NAME, OPTION_GENDER, OPTION_AGE, OPTION_SKIN, OPTION_HAIR, OPTION_CONFIRM]
@trainerPreview = TrainerClothesPreview.new(300, 80, false, "POKEBALL")
@trainerPreview.show()
@closed = false
@current_index = 0
@view.setMaxIndex(@options.length - 1)
end
def main()
pbSEPlay("GUI naming tab swap start", 80, 100)
@current_index = 0
loop do
@view.updateGraphics()
if Input.trigger?(Input::DOWN)
@current_index = move_menu_vertical(1)
elsif Input.trigger?(Input::UP)
@current_index = move_menu_vertical(-1)
elsif Input.trigger?(Input::RIGHT)
move_menu_horizontal(@current_index, 1)
elsif Input.trigger?(Input::LEFT)
move_menu_horizontal(@current_index, -1)
elsif Input.trigger?(Input::ACTION) || Input.trigger?(Input::USE)
action_button_pressed(@current_index)
end
break if @closed
end
end
def updateTrainerPreview
@trainerPreview.resetOutfits
@trainerPreview.updatePreview
end
def action_button_pressed(current_index)
selected_option = @options[current_index]
case selected_option
when OPTION_NAME
pbSEPlay("GUI summary change page", 80, 100)
@name = pbEnterPlayerName(_INTL("Enter your name"), 0, Settings::MAX_PLAYER_NAME_SIZE)
@name = getDefaultName() if @name == ''
pbSEPlay("GUI trainer card open", 80, 100)
updateDisplayedName(current_index)
applyHair() #for easter egg lol
when OPTION_CONFIRM
pbSEPlay("GUI save choice", 80, 100)
@current_index = @options.length - 1
update_cursor(@current_index)
@name = getDefaultName if @name == ""
updateDisplayedName(getOptionIndex(OPTION_NAME))
cmd = pbMessage("Is this information correct?", [_INTL("Yes"), _INTL("No")])
if cmd == 0
pbSEPlay("GUI naming confirm", 80, 100)
#pbMessage("You will be able to customize your appearance further while playing")
applyAllSelectedValues()
close_menu()
end
else
pbSEPlay("GUI save choice", 80, 100)
@current_index = @options.length - 1
update_cursor(@current_index)
@name = getDefaultName if @name == ""
updateDisplayedName(getOptionIndex(OPTION_NAME))
end
end
def getDefaultName()
return DEFAULT_NAMES[@gender]
end
def updateDisplayedName(current_index)
@view.displayText(NAME_TEXT_ID, @name, current_index)
end
def applyAllSelectedValues
applyGender(@gender)
echoln @age
pbSet(VAR_TRAINER_AGE, @age)
$Trainer.skin_tone = @skinTone
$Trainer.name = @name
end
def getOptionIndex(option_name)
i = 0
for option in @options
return i if option == option_name
i += 1
end
return -1
end
#VERTICAL NAVIGATION
def move_menu_vertical(offset)
pbSEPlay("GUI sel decision", 80, 100)
@current_index += offset
@current_index = 0 if @current_index > @options.length - 1
@current_index = @options.length - 1 if @current_index <= -1
update_cursor(@current_index)
return @current_index
end
def update_cursor(index)
@view.sprites["select"].y = @view.get_cursor_y_position(index)
@view.sprites["select"].x = @view.get_cursor_x_position(index)
set_custom_cursor(index)
end
def close_menu
@trainerPreview.erase()
Kernel.pbClearNumber()
Kernel.pbClearText()
pbDisposeSpriteHash(@view.sprites)
pbDisposeSpriteHash(@view.textValues)
@closed = true
end
def set_custom_cursor(index)
selected_option = @options[index]
case selected_option
when OPTION_GENDER
@view.showSideArrows(index)
when OPTION_AGE
@view.showSideArrows(index)
when OPTION_HAIR
@view.showSideArrows(index)
when OPTION_SKIN
@view.showSideArrows(index)
else
@view.hideSideArrows
end
end
#HORIZONTAL NAVIGATION
def move_menu_horizontal(current_index, incr)
pbSEPlay("GUI sel cursor", 80, 100)
selected_option = @options[current_index]
case selected_option
when OPTION_GENDER then
setGender(current_index, incr)
when OPTION_HAIR then
setHairColor(current_index, incr)
when OPTION_SKIN then
setSkinColor(current_index, incr)
when OPTION_AGE then
setAge(current_index, incr)
end
updateTrainerPreview()
end
def setGender(current_index, incr)
@gender += incr
@gender = 0 if @gender >= 2
@gender = 1 if @gender <= -1
applyGender(@gender)
label = GENDERS_IDS[@gender]
@view.displayText(GENDERS_IDS, label, current_index)
end
def setSkinColor(current_index, incr)
@skinTone += incr
@skinTone = MIN_SKIN_COLOR if @skinTone > MAX_SKIN_COLOR
@skinTone = MAX_SKIN_COLOR if @skinTone < MIN_SKIN_COLOR
$Trainer.skin_tone = @skinTone
label = SKIN_COLOR_IDS[@skinTone - 1]
@view.displayText(SKIN_TEXT_ID, label, current_index)
end
def setHairColor(current_index, incr)
max_id = HAIR_COLOR_IDS.length - 1
@hairColor += incr
@hairColor = 0 if @hairColor > max_id
@hairColor = max_id if @hairColor <= -1
applyHair()
@view.displayText(HAIR_TEXT_ID, HAIR_COLOR_NAMES[@hairColor], current_index)
end
def applyHair()
applyHairEasterEggs()
hairColorId = HAIR_COLOR_IDS[@hairColor]
hairId = hairColorId.to_s + "_" + @hairstyle.to_s
$Trainer.hair = hairId
end
def applyHairEasterEggs()
@hairstyle = HAIR_RIVAL if @name == "Gary" && @gender == 1
@hairstyle = HAIR_BROCK if @name == "Brock" && @gender == 1
@hairstyle = HAIR_MISTY1 if @name == "Misty" && @gender == 0
end
def applyGender(gender_index)
# outfitId = gender + 1
pbSet(VAR_TRAINER_GENDER, gender_index)
outfitId = get_outfit_id_from_index(gender_index)
@hairstyle = outfitId
applyHair()
#$Trainer.hair = outfitId
$Trainer.clothes = outfitId
$Trainer.hat = outfitId
end
def get_outfit_id_from_index(gender_index)
if gender_index == 1 #Male
return "red"
else
#Female
return "leaf"
end
end
#AGE
def setAge(y_index, incr)
@age += incr
@age = MIN_AGE if @age > MAX_AGE
@age = MAX_AGE if @age < MIN_AGE
@view.displayAge(@age, y_index)
end
def setInitialValues()
genderIndex = getOptionIndex(OPTION_GENDER)
hairIndex = getOptionIndex(OPTION_HAIR)
skinIndex = getOptionIndex(OPTION_SKIN)
ageIndex = getOptionIndex(OPTION_AGE)
setGender(genderIndex, 0)
setAge(ageIndex, 0)
setHairColor(hairIndex, 0)
setSkinColor(skinIndex, 0)
updateTrainerPreview()
end
end

View File

@@ -0,0 +1,265 @@
def playOutfitRemovedAnimation()
pbSEPlay("shiny", 80, 60)
$scene.spriteset.addUserAnimation(Settings::OW_SHINE_ANIMATION_ID, $game_player.x, $game_player.y, true)
end
def playOutfitChangeAnimation()
pbSEPlay("shiny", 80, 100)
$scene.spriteset.addUserAnimation(Settings::OW_SHINE_ANIMATION_ID, $game_player.x, $game_player.y, true)
end
def selectHairstyle(all_unlocked = false)
selector = OutfitSelector.new
display_outfit_preview()
hat = $Trainer.hat
commands = ["Next style", "Previous style", "Toggle hat", "Back"]
previous_input = 0
# To enable turning the common event that lets you turn around while in the dialog box
while (true)
choice = pbShowCommands(nil, commands, commands.length, previous_input)
previous_input = choice
case choice
when 0 #NEXT
playOutfitChangeAnimation()
selector.changeToNextHairstyle(1, all_unlocked)
display_outfit_preview()
when 1 #PREVIOUS
playOutfitChangeAnimation()
selector.changeToNextHairstyle(-1, all_unlocked)
display_outfit_preview()
when 2 #Toggle hat
pbSEPlay("GUI storage put down", 80, 100)
if hat == $Trainer.hat
$Trainer.hat = nil
else
$Trainer.hat = hat
end
display_outfit_preview()
else
break
end
end
hide_outfit_preview()
$Trainer.hat = hat
end
def swapToNextHairVersion()
split_hair = getSplitHairFilenameAndVersionFromID($Trainer.hair)
hair_version = split_hair[0]
hair_style = split_hair[1]
current_version = hair_version
pbSEPlay("GUI party switch", 80, 100)
newVersion = current_version.to_i + 1
lastVersion = findLastHairVersion(hair_style)
newVersion = lastVersion if newVersion <= 0
newVersion = 1 if newVersion > lastVersion
$Trainer.hair = getFullHairId(hair_style,newVersion)
end
def selectHairColor
original_color = $Trainer.hair_color
original_hair = $Trainer.hair
$game_switches[SWITCH_SELECTING_CLOTHES]=true
$game_map.update
display_outfit_preview()
hat = $Trainer.hat
commands = ["Swap base color", "Shift up", "Shift down", "Toggle hat", "Remove dye", "Confirm", "Never Mind"]
previous_input = 0
while (true)
choice = pbShowCommands(nil, commands, commands.length, previous_input)
previous_input = choice
case choice
when 0 #change base
swapToNextHairVersion()
display_outfit_preview()
ret = false
when 1 #NEXT
#playOutfitChangeAnimation()
pbSEPlay("GUI storage pick up", 80, 100)
shiftHairColor(10)
display_outfit_preview()
ret = true
when 2 #PREVIOUS
pbSEPlay("GUI storage pick up", 80, 100)
shiftHairColor(-10)
display_outfit_preview()
ret = true
when 3 #Toggle hat
pbSEPlay("GUI storage put down", 80, 100)
if hat == $Trainer.hat
$Trainer.hat = nil
else
$Trainer.hat = hat
end
display_outfit_preview()
when 4 #Reset
pbSEPlay("GUI storage put down", 80, 100)
$Trainer.hair_color = 0
display_outfit_preview()
ret = false
when 5 #Confirm
break
else
$Trainer.hair_color = original_color
$Trainer.hair = original_hair
ret = false
break
end
end
hide_outfit_preview()
$Trainer.hat = hat
$game_switches[SWITCH_SELECTING_CLOTHES]=false
$game_map.update
return ret
end
def selectHatColor(secondary_hat=false)
original_color = secondary_hat ? $Trainer.hat2_color : $Trainer.hat_color
display_outfit_preview()
commands = ["Shift up", "Shift down", "Reset", "Confirm", "Never Mind"]
previous_input = 0
while (true)
choice = pbShowCommands(nil, commands, commands.length, previous_input)
previous_input = choice
case choice
when 0 #NEXT
pbSEPlay("GUI storage pick up", 80, 100)
shiftHatColor(10,secondary_hat)
display_outfit_preview
ret = true
when 1 #PREVIOUS
pbSEPlay("GUI storage pick up", 80, 100)
shiftHatColor(-10,secondary_hat)
display_outfit_preview
ret = true
when 2 #Reset
pbSEPlay("GUI storage put down", 80, 100)
$Trainer.hat_color = 0 if !secondary_hat
$Trainer.hat2_color = 0 if secondary_hat
display_outfit_preview
refreshPlayerOutfit
ret = false
when 3 #Confirm
break
else
$Trainer.hat_color = original_color if !secondary_hat
$Trainer.hat2_color = original_color if secondary_hat
ret = false
break
end
end
refreshPlayerOutfit()
hide_outfit_preview()
return ret
end
def selectClothesColor
original_color = $Trainer.clothes_color
display_outfit_preview()
commands = ["Shift up", "Shift down", "Reset", "Confirm", "Never Mind"]
previous_input = 0
ret = false
while (true)
choice = pbShowCommands(nil, commands, commands.length, previous_input)
previous_input = choice
case choice
when 0 #NEXT
pbSEPlay("GUI storage pick up", 80, 100)
shiftClothesColor(10)
display_outfit_preview()
ret = true
when 1 #PREVIOUS
pbSEPlay("GUI storage pick up", 80, 100)
shiftClothesColor(-10)
display_outfit_preview()
ret = true
when 2 #Reset
pbSEPlay("GUI storage pick up", 80, 100)
$Trainer.clothes_color = 0
display_outfit_preview()
refreshPlayerOutfit()
ret = false
when 3 #Confirm
break
else
$Trainer.clothes_color = original_color
ret = false
break
end
end
refreshPlayerOutfit()
hide_outfit_preview()
return ret
end
def selectHat(all_unlocked = false)
selector = OutfitSelector.new
display_outfit_preview()
commands = ["Next hat", "Previous hat", "Remove hat", "Back"]
previous_input = 0
while (true)
choice = pbShowCommands(nil, commands, commands.length, previous_input)
previous_input = choice
case choice
when 0 #NEXT
playOutfitChangeAnimation()
selector.changeToNextHat(1, all_unlocked)
display_outfit_preview()
when 1 #PREVIOUS
playOutfitChangeAnimation()
selector.changeToNextHat(-1, all_unlocked)
display_outfit_preview()
when 2 #REMOVE HAT
playOutfitRemovedAnimation()
$Trainer.hat = nil
selector.display_outfit_preview()
else
break
end
end
hide_outfit_preview()
end
def spinCharacter
pbSEPlay("GUI party switch", 80, 100)
end
def selectClothes(all_unlocked = false)
selector = OutfitSelector.new
display_outfit_preview()
commands = ["Next", "Previous"]
#commands << "Remove clothes (DEBUG)" if $DEBUG
commands << "Remove" if $DEBUG
commands << "Back"
previous_input = 0
while (true)
choice = pbShowCommands(nil, commands, commands.length, previous_input)
previous_input = choice
case choice
when 0 #NEXT
playOutfitChangeAnimation()
selector.changeToNextClothes(1, all_unlocked)
display_outfit_preview()
when 1 #PREVIOUS
playOutfitChangeAnimation()
selector.changeToNextClothes(-1, all_unlocked)
display_outfit_preview()
when 2 #REMOVE CLOTHES
break if !$DEBUG
playOutfitRemovedAnimation()
$Trainer.clothes = nil
display_outfit_preview()
else
break
end
end
hide_outfit_preview()
end
def place_hat_on_pokemon(pokemon)
hatscreen = PokemonHatPresenter.new(nil, pokemon)
hatscreen.pbStartScreen()
end

View File

@@ -0,0 +1,103 @@
class PokemonHatPresenter
PIXELS_PER_MOVEMENT = 4
def initialize(view, pokemon)
@view = view
@pokemon = pokemon
@hatFilename = "Graphics/Characters/player/hat/trainer/hat_trainer_1"
@sprites = {}
@x_pos = pokemon.hat_x ? pokemon.hat_x : 0
@y_pos = pokemon.hat_y ? pokemon.hat_y : 0
@hat_id = pokemon.hat ? pokemon.hat : 1
@viewport = nil
@previewwindow = nil
@original_pokemon_bitmap = nil
end
def pbStartScreen
@view.init_window(self)
cancel if !select_hat()
if position_hat()
updatePokemonHatPosition()
else
cancel
end
@view.hide_move_arrows
@view.hide_select_arrows
@view.dispose_window()
end
def updatePokemonHatPosition()
@pokemon.hat = @hat_id
@pokemon.hat_x = @x_pos
@pokemon.hat_y = @y_pos
end
def cancel
@pokemon.hat = nil
end
def select_hat
selector = OutfitSelector.new
@view.display_select_arrows
outfit_type_path = get_hats_sets_list_path()
@pokemon.hat = 0 if !@pokemon.hat
loop do
Graphics.update
Input.update
@hat_id = selector.selectNextOutfit(@hat_id, 1, selector.hats_list, [], false, "hat",$Trainer.unlocked_hats,false) if Input.trigger?(Input::RIGHT)
@hat_id = selector.selectNextOutfit(@hat_id, -1, selector.hats_list, [], false, "hat",$Trainer.unlocked_hats,false) if Input.trigger?(Input::LEFT)
break if Input.trigger?(Input::USE)
return false if Input.trigger?(Input::BACK)
@view.update()
end
@pokemon.hat = @hat_id
@view.hide_select_arrows
end
def position_hat
@view.display_move_arrows
min_x, max_x = -64, 88
min_y, max_y = -20, 140
loop do
Graphics.update
Input.update
@x_pos += PIXELS_PER_MOVEMENT if Input.repeat?(Input::RIGHT) && @x_pos < max_x
@x_pos -= PIXELS_PER_MOVEMENT if Input.repeat?(Input::LEFT) && @x_pos > min_x
@y_pos += PIXELS_PER_MOVEMENT if Input.repeat?(Input::DOWN) && @y_pos < max_y
@y_pos -= PIXELS_PER_MOVEMENT if Input.repeat?(Input::UP) && @y_pos > min_y
break if Input.trigger?(Input::USE)
return false if Input.trigger?(Input::BACK)
@view.update()
end
@view.hide_move_arrows
return true
end
def initialize_bitmap()
spriteLoader = BattleSpriteLoader.new
if @pokemon.isTripleFusion?
#todo
elsif @pokemon.isFusion?
@original_pokemon_bitmap = spriteLoader.load_fusion_sprite(@pokemon.head_id(),@pokemon.body_id())
else
echoln @pokemon
echoln @pokemon.species_data
@original_pokemon_bitmap = spriteLoader.load_base_sprite(@pokemon.id_number)
end
@original_pokemon_bitmap.scale_bitmap(Settings::FRONTSPRITE_SCALE)
end
def getPokemonHatBitmap()
@hatFilename = getTrainerSpriteHatFilename(@hat_id)
hatBitmapWrapper = AnimatedBitmap.new(@hatFilename, 0) if pbResolveBitmap(@hatFilename)
pokemon_bitmap = @original_pokemon_bitmap.bitmap.clone
pokemon_bitmap.blt(@x_pos, @y_pos, hatBitmapWrapper.bitmap, hatBitmapWrapper.bitmap.rect) if hatBitmapWrapper
return pokemon_bitmap
end
end

View File

@@ -0,0 +1,139 @@
class PokemonHatView
WINDOW_POS_X = Graphics.width / 4
WINDOW_POS_Y = Graphics.height / 8
attr_accessor :x_pos
attr_accessor :y_pos
def initialize(x_pos = nil, y_pos = nil, windowed = true)
@x_pos = x_pos ? x_pos : WINDOW_POS_X
@y_pos = y_pos ? y_pos : WINDOW_POS_Y
@windowed = windowed
end
def init_window(presenter)
@presenter = presenter
presenter.initialize_bitmap()
pokemon_bitmap = presenter.getPokemonHatBitmap()
@previewwindow = PictureWindow.new(pokemon_bitmap)
@previewwindow.opacity = 0 if !@windowed
update_window_position()
@previewwindow.z = 9999999
@viewport = Viewport.new(@previewwindow.x, @previewwindow.y, @previewwindow.width, @previewwindow.height)
@viewport.z = 9999999
@sprites = {}
initialize_arrows()
end
def getWindowWidth()
return @previewwindow.width/2
end
def initialize_arrows()
middle_horizontal = 100
width_horizontal = 90
middle_vertical = 100
width_vertical = 90
@sprites["uparrow"] = AnimatedSprite.new("Graphics/Pictures/uparrow", 8, 28, 40, 2, @viewport)
@sprites["uparrow"].x = middle_horizontal
@sprites["uparrow"].y = middle_vertical - width_vertical
@sprites["uparrow"].z = 100
@sprites["uparrow"].visible=true
@sprites["downarrow"] = AnimatedSprite.new("Graphics/Pictures/downarrow", 8, 28, 40, 2, @viewport)
@sprites["downarrow"].x = middle_horizontal
@sprites["downarrow"].y = middle_vertical + width_vertical
@sprites["leftarrow"] = AnimatedSprite.new("Graphics/Pictures/leftarrow", 8, 40, 28, 2, @viewport)
@sprites["leftarrow"].x = middle_horizontal - width_horizontal -10
@sprites["leftarrow"].y = middle_vertical
@sprites["rightarrow"] = AnimatedSprite.new("Graphics/Pictures/rightarrow", 8, 40, 28, 2, @viewport)
@sprites["rightarrow"].x = middle_horizontal + width_horizontal
@sprites["rightarrow"].y = middle_vertical
@sprites["uparrow"].visible=false
@sprites["downarrow"].visible=false
@sprites["leftarrow"].visible=false
@sprites["rightarrow"].visible=false
end
def update_window_position()
@previewwindow.x = @x_pos
@previewwindow.y = @y_pos
end
#TODO
def display_select_arrows
hide_move_arrows
@sprites["rightarrow"].visible=true
@sprites["leftarrow"].visible=true
@sprites["rightarrow"].play
@sprites["leftarrow"].play
end
def hide_select_arrows
@sprites["rightarrow"].visible=false
@sprites["leftarrow"].visible=false
@sprites["rightarrow"].stop
@sprites["leftarrow"].stop
@sprites["rightarrow"].reset
@sprites["leftarrow"].reset
end
def display_move_arrows
hide_move_arrows
@sprites["rightarrow"].visible=true
@sprites["leftarrow"].visible=true
@sprites["uparrow"].visible=true
@sprites["downarrow"].visible=true
@sprites["rightarrow"].play
@sprites["leftarrow"].play
@sprites["uparrow"].play
@sprites["downarrow"].play
end
def hide_move_arrows
@sprites["rightarrow"].visible=false
@sprites["leftarrow"].visible=false
@sprites["uparrow"].visible=false
@sprites["downarrow"].visible=false
@sprites["rightarrow"].stop
@sprites["leftarrow"].stop
@sprites["uparrow"].stop
@sprites["downarrow"].stop
end
def dispose_window
@previewwindow.dispose
@viewport.dispose
pbDisposeSpriteHash(@sprites)
@sprites = nil
end
def update
@sprites["rightarrow"].update
@sprites["leftarrow"].update
@sprites["uparrow"].update
@sprites["downarrow"].update
@previewwindow.clearBitmaps
@previewwindow.setBitmap(@presenter.getPokemonHatBitmap())
@previewwindow.update
end
end

View File

@@ -0,0 +1,72 @@
class TrainerClothesPreview
attr_writer :pokeball, :clothes, :hat, :hat2, :hair, :skin_tone, :hair_color, :hat_color,:hat2_color, :clothes_color
def initialize(x = 0, y = 0, windowed = true, pokeball = nil)
@playerBitmap = nil
@playerSprite = nil
@x_pos = x
@y_pos = y
@windowed = windowed
@pokeball = pokeball
resetOutfits()
end
def set_hat(value,is_secondaryHat=false)
if is_secondaryHat
@hat2 = value
else
@hat = value
end
end
def set_hat_color(value,is_secondaryHat=false)
if is_secondaryHat
@hat2_color = value
else
@hat_color = value
end
end
def resetOutfits()
@clothes = $Trainer.clothes
@hat = $Trainer.hat
@hat2 = $Trainer.hat2
@hair = $Trainer.hair
@skin_tone = $Trainer.skin_tone
@hair_color = $Trainer.hair_color
@hat_color = $Trainer.hat_color
@hat2_color = $Trainer.hat2_color
@clothes_color = $Trainer.clothes_color
end
def show()
@playerBitmap = generate_front_trainer_sprite_bitmap(false,
@pokeball,
@clothes,
@hat,@hat2, @hair,
@skin_tone,
@hair_color, @hat_color, @clothes_color, @hat2_color)
initialize_preview()
end
def updatePreview()
erase()
show()
end
def initialize_preview()
@playerSprite = PictureWindow.new(@playerBitmap)
@playerSprite.opacity = 0 if !@windowed
@playerSprite.x = @x_pos
@playerSprite.y = @y_pos
@playerSprite.z = 9999
@playerSprite.update
end
def erase()
@playerSprite.dispose if @playerSprite
end
end

View File

@@ -0,0 +1,159 @@
class OutfitsMartAdapter < PokemonMartAdapter
attr_accessor :worn_clothes
attr_accessor :is_secondary_hat
attr_accessor :items
WORN_ITEM_BASE_COLOR = MessageConfig::BLUE_TEXT_MAIN_COLOR
WORN_ITEM_SHADOW_COLOR = MessageConfig::BLUE_TEXT_SHADOW_COLOR
REGIONAL_SET_BASE_COLOR = Color.new(76,72,104)
REGIONAL_SET_SHADOW_COLOR = Color.new(173,165,189)
CITY_EXCLUSIVE_BASE_COLOR = Color.new(61 , 125, 70) #Color.new(72 , 104, 83)
CITY_EXCLUSIVE_SHADOW_COLOR = Color.new(165, 189, 178)
def initialize(stock = [], isShop = true, isSecondaryHat = false)
@is_secondary_hat = isSecondaryHat
@items = stock
@worn_clothes = get_current_clothes()
@isShop = isShop
@version = nil
$Trainer.dyed_hats = {} if !$Trainer.dyed_hats
$Trainer.dyed_clothes = {} if !$Trainer.dyed_clothes
#todo: refactor to get the list from the first search when
# setting the stock instead of searching twice
@regional_set_items = @isShop ? list_regional_set_items : []
@city_exclusive_items = @isShop ? list_city_exclusive_items : []
end
def list_regional_set_items()
return []
end
def list_city_exclusive_items()
return []
end
def getDisplayName(item)
return getName(item) if !item.name
name = item.name
name = "* #{name}" if is_wearing_clothes(item.id)
return name
end
def is_wearing_clothes(outfit_id)
return outfit_id == @worn_clothes
end
def player_changed_clothes?()
return false
#implement in inheriting classes
end
def toggleText()
return ""
end
def switchVersion(item,delta=1)
return
end
def toggleEvent(item)
return
end
def isWornItem?(item)
return false
end
def isShop?()
return @isShop
end
def getPrice(item, selling = nil)
return 0 if !@isShop
return nil if itemOwned(item)
return item.price.to_i
end
def getDisplayPrice(item, selling = nil)
return "" if !@isShop
return "-" if itemOwned(item)
super
end
def updateStock()
updated_items = []
for item in @items
updated_items << item if !get_unlocked_items_list().include?(item.id)
end
@items = updated_items
end
def removeItem(item)
super
end
def itemOwned(item)
owned_list = get_unlocked_items_list()
return owned_list.include?(item.id)
end
def canSell?(item)
super
end
def isItemInRegionalSet(item)
return @regional_set_items.include?(item.id)
end
def isItemCityExclusive(item)
return @city_exclusive_items.include?(item.id)
end
def getBaseColorOverride(item)
return REGIONAL_SET_BASE_COLOR if isItemInRegionalSet(item)
return CITY_EXCLUSIVE_BASE_COLOR if isItemCityExclusive(item)
return nil
end
def getShadowColorOverride(item)
return REGIONAL_SET_SHADOW_COLOR if isItemInRegionalSet(item)
return CITY_EXCLUSIVE_SHADOW_COLOR if isItemCityExclusive(item)
return nil
end
def getMoney
super
end
def getMoneyString
super
end
def setMoney(value)
super
end
def getItemIconRect(_item)
super
end
def getQuantity(item)
super
end
def showQuantity?(item)
super
end
def updateVersion(item)
@version = 1 if !currentVersionExists?(item)
end
def currentVersionExists?(item)
return true
end
end

View File

@@ -0,0 +1,116 @@
class ClothesMartAdapter < OutfitsMartAdapter
DEFAULT_NAME = "[unknown]"
DEFAULT_DESCRIPTION = "A piece of clothing that trainers can wear."
def toggleEvent(item)
if !isShop? && $Trainer.clothes_color != 0
if pbConfirmMessage(_INTL("Would you like to remove the dye?"))
$Trainer.clothes_color = 0
end
end
end
def list_regional_set_items()
return list_regional_clothes
end
def list_city_exclusive_items
return list_city_exclusive_clothes
end
def initialize(stock = nil, isShop = nil)
super
end
def getName(item)
name= item.id
name = "* #{name}" if is_wearing_clothes(item.id)
return name
end
def getDescription(item)
return DEFAULT_DESCRIPTION if !item.description
return item.description
end
def getItemIcon(item)
return Settings::BACK_ITEM_ICON_PATH if !item
return getOverworldOutfitFilename(item.id)
end
def updateTrainerPreview(item, previewWindow)
return if !item
previewWindow.clothes = item.id
$Trainer.clothes = item.id
set_dye_color(item,previewWindow)
pbRefreshSceneMap
previewWindow.updatePreview()
end
def get_dye_color(item_id)
return 0 if isShop?
$Trainer.dyed_clothes= {} if ! $Trainer.dyed_clothes
if $Trainer.dyed_clothes.include?(item_id)
return $Trainer.dyed_clothes[item_id]
end
return 0
end
def set_dye_color(item,previewWindow)
if !isShop?
$Trainer.dyed_clothes= {} if ! $Trainer.dyed_clothes
if $Trainer.dyed_clothes.include?(item.id)
dye_color = $Trainer.dyed_clothes[item.id]
$Trainer.clothes_color = dye_color
previewWindow.clothes_color = dye_color
else
$Trainer.clothes_color=0
previewWindow.clothes_color=0
end
else
$Trainer.clothes_color=0
previewWindow.clothes_color=0
end
end
def addItem(item)
changed_clothes = obtainClothes(item.id)
if changed_clothes
@worn_clothes = item.id
end
end
def get_current_clothes()
return $Trainer.clothes
end
def player_changed_clothes?()
$Trainer.clothes != @worn_clothes
end
def putOnSelectedOutfit()
putOnClothes($Trainer.clothes)
@worn_clothes = $Trainer.clothes
end
def putOnOutfit(item)
putOnClothes(item.id) if item
@worn_clothes = item.id if item
end
def reset_player_clothes()
$Trainer.clothes = @worn_clothes
$Trainer.clothes_color = $Trainer.dyed_clothes[@worn_clothes] if $Trainer.dyed_clothes && $Trainer.dyed_clothes[@worn_clothes]
end
def get_unlocked_items_list()
return $Trainer.unlocked_clothes
end
def isWornItem?(item)
super
end
end

View File

@@ -0,0 +1,146 @@
def genericOutfitsShopMenu(stock = [], itemType = nil, versions = false, isShop=true, message=nil)
commands = []
commands[cmdBuy = commands.length] = _INTL("Buy")
commands[cmdQuit = commands.length] = _INTL("Quit")
message = _INTL("Welcome! How may I serve you?") if !message
cmd = pbMessage(message, commands, cmdQuit + 1)
loop do
if cmdBuy >= 0 && cmd == cmdBuy
adapter = getAdapter(itemType, stock, isShop)
view = ClothesShopView.new()
presenter = getPresenter(itemType, view, stock, adapter, versions)
presenter.pbBuyScreen
break
else
pbMessage(_INTL("Please come again!"))
break
end
end
end
def getPresenter(itemType, view, stock, adapter, versions)
case itemType
when :HAIR
return HairShopPresenter.new(view, stock, adapter, versions)
else
return ClothesShopPresenter.new(view, stock, adapter, versions)
end
end
def getAdapter(itemType, stock, isShop, is_secondary=false)
case itemType
when :CLOTHES
return ClothesMartAdapter.new(stock, isShop)
when :HAT
return HatsMartAdapter.new(stock, isShop,is_secondary)
when :HAIR
return HairMartAdapter.new(stock, isShop)
end
end
def list_all_possible_outfits() end
def clothesShop(outfits_list = [], free=false,customMessage=nil)
stock = []
outfits_list.each { |outfit_id|
outfit = get_clothes_by_id(outfit_id)
stock << outfit if outfit
}
genericOutfitsShopMenu(stock, :CLOTHES,false,!free,customMessage)
end
def hatShop(outfits_list = [], free=false, customMessage=nil)
stock = []
outfits_list.each { |outfit_id|
outfit = get_hat_by_id(outfit_id)
stock << outfit if outfit
}
genericOutfitsShopMenu(stock, :HAT,false,!free,customMessage)
end
def hairShop(outfits_list = [],free=false, customMessage=nil)
currentHair = getSimplifiedHairIdFromFullID($Trainer.hair)
stock = [:SWAP_COLOR]
#always add current hairstyle as first option (in case the player just wants to swap the color)
stock << get_hair_by_id(currentHair) if $Trainer.hair
outfits_list.each { |outfit_id|
next if outfit_id == currentHair
outfit = get_hair_by_id(outfit_id)
stock << outfit if outfit
}
genericOutfitsShopMenu(stock, :HAIR, true,!free,customMessage)
end
def switchHatsPosition()
hat1 = $Trainer.hat
hat2 = $Trainer.hat2
hat1_color = $Trainer.hat_color
hat2_color = $Trainer.hat2_color
$Trainer.hat = hat2
$Trainer.hat2 = hat1
$Trainer.hat_color = hat1_color
$Trainer.hat_color = hat2_color
pbSEPlay("GUI naming tab swap start")
end
SWAP_HAT_POSITIONS_CAPTION = "Switch hats position"
#is_secondary only used for hats
def openSelectOutfitMenu(stock = [], itemType =nil, is_secondary=false)
adapter = getAdapter(itemType, stock, false, is_secondary)
view = getView(itemType)
presenter = ClothesShopPresenter.new(view, stock, adapter)
presenter.pbBuyScreen
end
def getView(itemType)
case itemType
when :HAT
return HatShopView.new
else
return ClothesShopView.new
end
end
def changeClothesMenu()
stock = []
$Trainer.unlocked_clothes.each { |outfit_id|
outfit = get_clothes_by_id(outfit_id)
stock << outfit if outfit
}
openSelectOutfitMenu(stock, :CLOTHES)
end
def changeHatMenu(is_secondary_hat = false)
stock = []
$Trainer.unlocked_hats.each { |outfit_id|
outfit = get_hat_by_id(outfit_id)
stock << outfit if outfit
}
stock << :REMOVE_HAT
openSelectOutfitMenu(stock, :HAT, is_secondary_hat)
end
def changeOutfit()
commands = []
commands[cmdHat = commands.length] = _INTL("Change hat")
commands[cmdClothes = commands.length] = _INTL("Change clothes")
commands[cmdQuit = commands.length] = _INTL("Quit")
cmd = pbMessage(_INTL("What would you like to do?"), commands, cmdQuit + 1)
loop do
if cmd == cmdClothes
changeClothesMenu()
break
elsif cmd == cmdHat
changeHatMenu()
break
else
break
end
end
end

View File

@@ -0,0 +1,163 @@
class ClothesShopPresenter < PokemonMartScreen
def pbChooseBuyItem
end
def initialize(scene, stock, adapter = nil, versions = false)
super(scene, stock, adapter)
@use_versions = versions
end
def putOnClothes(item,end_scene=true)
@adapter.putOnOutfit(item) if item
@scene.pbEndBuyScene if end_scene
end
def dyeClothes()
original_color = $Trainer.clothes_color
options = ["Shift up", "Shift down", "Reset", "Confirm", "Never Mind"]
previous_input = 0
ret = false
while (true)
choice = pbShowCommands(nil, options, options.length, previous_input,200)
previous_input = choice
case choice
when 0 #NEXT
pbSEPlay("GUI storage pick up", 80, 100)
shiftClothesColor(10)
ret = true
when 1 #PREVIOUS
pbSEPlay("GUI storage pick up", 80, 100)
shiftClothesColor(-10)
ret = true
when 2 #Reset
pbSEPlay("GUI storage pick up", 80, 100)
$Trainer.clothes_color = 0
ret = false
when 3 #Confirm
break
else
$Trainer.clothes_color = original_color
ret = false
break
end
@scene.updatePreviewWindow
end
return ret
end
# returns true if should stay in the menu
def playerClothesActionsMenu(item)
cmd_wear = "Wear"
cmd_dye = "Dye Kit"
options = []
options << cmd_wear
options << cmd_dye if $PokemonBag.pbHasItem?(:CLOTHESDYEKIT)
options << "Cancel"
choice = pbMessage("What would you like to do?", options, -1)
if options[choice] == cmd_wear
putOnClothes(item,false)
$Trainer.clothes_color = @adapter.get_dye_color(item.id)
return true
elsif options[choice] == cmd_dye
dyeClothes()
end
return true
end
def confirmPutClothes(item)
putOnClothes(item)
end
def quitMenuPrompt()
return true if !(@adapter.is_a?(HatsMartAdapter) || @adapter.is_a?(ClothesMartAdapter))
boolean_changes_detected = @adapter.player_changed_clothes?
return true if !boolean_changes_detected
pbPlayCancelSE
cmd_confirm = "Set outfit"
cmd_discard = "Discard changes"
cmd_cancel = "Cancel"
options = [cmd_discard,cmd_confirm,cmd_cancel]
choice = pbMessage("You have unsaved changes!",options,3)
case options[choice]
when cmd_confirm
@adapter.putOnSelectedOutfit
pbPlayDecisionSE
return true
when cmd_discard
pbPlayCloseMenuSE
return true
else
return false
end
end
def pbBuyScreen
@scene.pbStartBuyScene(@stock, @adapter)
@scene.select_specific_item(@adapter.worn_clothes) if !@adapter.isShop?
item = nil
loop do
item = @scene.pbChooseBuyItem
if !item
break if @adapter.isShop?
#quit_menu_choice = quitMenuPrompt()
#break if quit_menu_choice
break
next
end
if !@adapter.isShop?
if @adapter.is_a?(ClothesMartAdapter)
stay_in_menu = playerClothesActionsMenu(item)
next if stay_in_menu
return
elsif @adapter.is_a?(HatsMartAdapter)
echoln pbGet(1)
stay_in_menu = playerHatActionsMenu(item)
echoln pbGet(1)
next if stay_in_menu
return
else
if pbConfirm(_INTL("Would you like to put on the {1}?", item.name))
confirmPutClothes(item)
return
end
next
end
next
end
itemname = @adapter.getDisplayName(item)
price = @adapter.getPrice(item)
if !price.is_a?(Integer)
pbDisplayPaused(_INTL("You already own this item!"))
if pbConfirm(_INTL("Would you like to put on the {1}?", item.name))
@adapter.putOnOutfit(item)
end
next
end
if @adapter.getMoney < price
pbDisplayPaused(_INTL("You don't have enough money."))
next
end
if !pbConfirm(_INTL("Certainly. You want {1}. That will be ${2}. OK?",
itemname, price.to_s_formatted))
next
end
if @adapter.getMoney < price
pbDisplayPaused(_INTL("You don't have enough money."))
next
end
@adapter.setMoney(@adapter.getMoney - price)
@stock.compact!
pbDisplayPaused(_INTL("Here you are! Thank you!")) { pbSEPlay("Mart buy item") }
@adapter.addItem(item)
end
@scene.pbEndBuyScene
end
end

View File

@@ -0,0 +1,154 @@
class ClothesShopPresenter < PokemonMartScreen
def removeHat(item)
pbSEPlay("GUI storage put down")
@adapter.toggleEvent(item)
@scene.select_specific_item(nil,true)
end
def wearAsHat1(item)
@adapter.set_secondary_hat(false)
putOnClothes(item)
$Trainer.set_hat_color(@adapter.get_dye_color(item.id),false)
end
def wearAsHat2(item)
@adapter.set_secondary_hat(true)
putOnClothes(item)
$Trainer.set_hat_color(@adapter.get_dye_color(item.id),true)
end
def removeDye(item)
if pbConfirm(_INTL("Are you sure you want to remove the dye from the {1}?", item.name))
$Trainer.set_hat_color(0,@adapter.is_secondary_hat)
end
end
def swapHats()
echoln "hat 1: #{$Trainer.hat}"
echoln "hat 2: #{$Trainer.hat2}"
$Trainer.hat, $Trainer.hat2 = $Trainer.hat2, $Trainer.hat
pbSEPlay("GUI naming tab swap start")
new_selected_hat = @adapter.is_secondary_hat ? $Trainer.hat2 : $Trainer.hat
echoln "hat 1: #{$Trainer.hat}"
echoln "hat 2: #{$Trainer.hat2}"
echoln "new selected hat: #{new_selected_hat}"
@scene.select_specific_item(new_selected_hat,true)
@scene.updatePreviewWindow
end
def build_options_menu(item,cmd_confirm,cmd_remove,cmd_dye,cmd_swap,cmd_cancel)
options = []
options << cmd_confirm
options << cmd_remove
options << cmd_swap
options << cmd_dye if $PokemonBag.pbHasItem?(:HATSDYEKIT)
options << cmd_cancel
end
def build_wear_options(cmd_wear_hat1,cmd_wear_hat2,cmd_replace_hat1,cmd_replace_hat2)
options = []
primary_hat, secondary_hat = @adapter.worn_clothes, @adapter.worn_clothes2
primary_cmds = primary_hat ? cmd_replace_hat1 : cmd_wear_hat1
secondary_cmds = secondary_hat ? cmd_replace_hat2 : cmd_wear_hat2
if @adapter.is_secondary_hat
options << secondary_cmds
options << primary_cmds
else
options << primary_cmds
options << secondary_cmds
end
return options
end
def putOnHats()
@adapter.worn_clothes = $Trainer.hat
@adapter.worn_clothes2 = $Trainer.hat2
putOnHat($Trainer.hat,true,false)
putOnHat($Trainer.hat2,true,true)
playOutfitChangeAnimation()
pbMessage(_INTL("You put on the hat(s)!\\wtnp[30]"))
end
def dyeOptions(secondary_hat=false,item)
original_color = secondary_hat ? $Trainer.hat2_color : $Trainer.hat_color
options = ["Shift up", "Shift down", "Reset", "Confirm", "Never Mind"]
previous_input = 0
while (true)
choice = pbShowCommands(nil, options, options.length, previous_input,200)
previous_input = choice
case choice
when 0 #NEXT
pbSEPlay("GUI storage pick up", 80, 100)
shiftHatColor(10,secondary_hat)
ret = true
when 1 #PREVIOUS
pbSEPlay("GUI storage pick up", 80, 100)
shiftHatColor(-10,secondary_hat)
ret = true
when 2 #Reset
pbSEPlay("GUI storage put down", 80, 100)
$Trainer.hat_color = 0 if !secondary_hat
$Trainer.hat2_color = 0 if secondary_hat
ret = false
when 3 #Confirm
break
else
$Trainer.hat_color = original_color if !secondary_hat
$Trainer.hat2_color = original_color if secondary_hat
ret = false
break
end
@scene.updatePreviewWindow
@scene.displayLayerIcons(item)
end
return ret
end
def confirmPutClothes(item)
if @adapter.is_a?(HatsMartAdapter)
putOnHats()
$Trainer.hat_color = @adapter.get_dye_color($Trainer.hat)
$Trainer.hat2_color = @adapter.get_dye_color($Trainer.hat2)
else
putOnClothes(item,false)
end
end
def playerHatActionsMenu(item)
cmd_confirm = "Confirm"
cmd_remove = "Remove hat"
cmd_cancel = "Cancel"
cmd_dye = "Dye Kit"
cmd_swap = "Swap hat positions"
options = build_options_menu(item,cmd_confirm,cmd_remove,cmd_dye,cmd_swap,cmd_cancel)
choice = pbMessage("What would you like to do?", options, -1,nil,0)
if options[choice] == cmd_remove
removeHat(item)
return true
elsif options[choice] == cmd_confirm
confirmPutClothes(nil)
return true
elsif options[choice] == cmd_dye
dyeOptions(@adapter.is_secondary_hat,item)
return true
elsif options[choice] == cmd_swap
swapHats()
return true
elsif options[choice] == "dye"
selectHatColor
end
@scene.updatePreviewWindow
return true
end
end

View File

@@ -0,0 +1,205 @@
class ClothesShopView < PokemonMart_Scene
def initialize(currency_name = "Money")
@currency_name = currency_name
end
def pbStartBuyOrSellScene(buying, stock, adapter)
super(buying, stock, adapter)
@sprites["icon"].visible = false
if @adapter.isShop?
@sprites["background"].setBitmap("Graphics/Pictures/Outfits/martScreenOutfit")
else
@sprites["background"].setBitmap("Graphics/Pictures/Outfits/changeOutfitScreen")
end
preview_y = @adapter.isShop? ? 80 : 0
@sprites["trainerPreview"] = TrainerClothesPreview.new(0, preview_y, true, "WALLET")
@sprites["trainerPreview"].show()
@sprites["moneywindow"].visible = false if !@adapter.isShop?
Kernel.pbDisplayText(@adapter.toggleText, 80, 200, 99999) if @adapter.toggleText
end
def select_specific_item(scroll_to_item_id,go_to_end_of_list_if_nil=false)
itemwindow = @sprites["itemwindow"]
if !scroll_to_item_id && go_to_end_of_list_if_nil
itemwindow.index=@adapter.items.length-1
itemwindow.refresh
end
i=0
for item in @adapter.items
next if !item.is_a?(Outfit)
if item.id == scroll_to_item_id
itemwindow.index=i
itemwindow.refresh
end
i+=1
end
end
def scroll_map
pbScrollMap(DIRECTION_UP, 5, 6)
pbScrollMap(DIRECTION_RIGHT, 7, 6)
@initial_direction = $game_player.direction
$game_player.turn_down
pbRefreshSceneMap
end
def scroll_back_map
@adapter.reset_player_clothes()
pbScrollMap(DIRECTION_LEFT, 7, 6)
pbScrollMap(DIRECTION_DOWN, 5, 6)
$game_player.turn_generic(@initial_direction)
end
def refreshStock(adapter)
@adapter = adapter
@sprites["itemwindow"].dispose if !@sprites
@sprites["itemwindow"] = Window_PokemonMart.new(@stock, BuyAdapter.new(adapter),
Graphics.width - 316 - 16, 12, 330 + 16, Graphics.height - 126)
end
def pbRefresh
if @subscene
@subscene.pbRefresh
else
itemwindow = @sprites["itemwindow"]
item = itemwindow.item
if itemwindow.item
if itemwindow.item.is_a?(Symbol)
text = @adapter.getSpecialItemCaption(item)
else
text = @adapter.getDescription(item)
end
else
text = _INTL("Quit.")
end
@sprites["itemtextwindow"].text = text
itemwindow.refresh
end
@sprites["moneywindow"].text = _INTL("{2}:\r\n<r>{1}", @adapter.getMoneyString, @currency_name)
end
def updateTrainerPreview()
displayNewItem(@sprites["itemwindow"])
end
def displayNewItem(itemwindow)
item = itemwindow.item
if item
if item.is_a?(Symbol)
description = @adapter.getSpecialItemDescription(itemwindow.item)
else
description = @adapter.getDescription(itemwindow.item)
@adapter.updateVersion(itemwindow.item)
end
@adapter.updateTrainerPreview(itemwindow.item, @sprites["trainerPreview"])
else
description = _INTL("Quit.")
end
@sprites["itemtextwindow"].text = description
end
def updatePreviewWindow
itemwindow= @sprites["itemwindow"]
@adapter.updateTrainerPreview(itemwindow.item, @sprites["trainerPreview"])
end
def pbChooseBuyItem
itemwindow = @sprites["itemwindow"]
refreshStock(@adapter) if !itemwindow
displayNewItem(itemwindow)
@sprites["helpwindow"].visible = false
pbActivateWindow(@sprites, "itemwindow") {
pbRefresh
loop do
Graphics.update
Input.update
olditem = itemwindow.item
self.update
if itemwindow.item != olditem
displayNewItem(itemwindow)
end
if Input.trigger?(Input::AUX1) #L button - disabled because same key as speed up...
#@adapter.switchVersion(itemwindow.item, -1)
#updateTrainerPreview()
end
if Input.trigger?(Input::AUX2) || Input.trigger?(Input::SHIFT) #R button
switchItemVersion(itemwindow)
end
if Input.trigger?(Input::SPECIAL) #R button
@adapter.toggleEvent(itemwindow.item)
updateTrainerPreview()
end
if Input.trigger?(Input::BACK)
pbPlayCloseMenuSE
return nil
elsif Input.trigger?(Input::USE)
if itemwindow.item.is_a?(Symbol)
ret = onSpecialActionTrigger(itemwindow)
return ret if ret
elsif itemwindow.index < @stock.length
pbRefresh
return @stock[itemwindow.index]
else
return nil
end
end
end
}
end
def onSpecialActionTrigger(itemwindow)
@adapter.doSpecialItemAction(itemwindow.item)
updateTrainerPreview()
return nil
end
def onItemClick(itemwindow)
if itemwindow.item.is_a?(Symbol)
@adapter.doSpecialItemAction(itemwindow.item)
updateTrainerPreview()
elsif itemwindow.index < @stock.length
pbRefresh
return @stock[itemwindow.index]
else
return nil
end
end
def switchItemVersion(itemwindow)
@adapter.switchVersion(itemwindow.item, 1)
updateTrainerPreview()
end
def update
if Input.trigger?(Input::LEFT)
pbSEPlay("GUI party switch", 80, 100)
$game_player.turn_right_90
pbRefreshSceneMap
end
if Input.trigger?(Input::RIGHT)
pbSEPlay("GUI party switch", 80, 100)
$game_player.turn_left_90
pbRefreshSceneMap
end
super
end
def pbEndBuyScene
if !@sprites.empty?
@sprites["trainerPreview"].erase()
@sprites["trainerPreview"] = nil
end
pbDisposeSpriteHash(@sprites)
@viewport.dispose
Kernel.pbClearText()
# Scroll left after showing screen
scroll_back_map()
end
end

View File

@@ -0,0 +1,209 @@
class HairMartAdapter < OutfitsMartAdapter
DEFAULT_NAME = "[unknown]"
DEFAULT_DESCRIPTION = "A hairstyle for trainers."
POSSIBLE_VERSIONS = (1..9).to_a
def initialize(stock = nil, isShop = nil)
super
@version = getCurrentHairVersion().to_i
@worn_hair = $Trainer.hair
@worn_hat = $Trainer.hat
@worn_hat2 = $Trainer.hat2
@hat_visible = false
@removable = true
@previous_item= find_first_item()
end
def find_first_item()
return @items.find { |item| item.is_a?(Outfit) }
end
def switchVersion(item, delta = 1)
if !item.is_a?(Outfit)
item = @previous_item
end
pbSEPlay("GUI party switch", 80, 100)
newVersion = @version + delta
lastVersion = findLastHairVersion(item.id)
newVersion = lastVersion if newVersion <= 0
newVersion = 1 if newVersion > lastVersion
@version = newVersion
end
def player_changed_clothes?()
$Trainer.hairstyle != @worn_hair
end
#player can't "own" hairstyles
# if you want to go back one you had before, you have to pay again
def itemOwned(item)
return false
end
def list_regional_set_items()
return list_regional_hairstyles
end
def list_city_exclusive_items
return list_city_exclusive_hairstyles
end
def toggleEvent(item)
pbSEPlay("GUI storage put down", 80, 100)
toggleHatVisibility()
end
def toggleText()
text = ""
#text << "Color: R, \n"
text << "Toggle Hat: D\n"
end
def toggleHatVisibility()
@hat_visible = !@hat_visible
end
def getPrice(item, selling = nil)
return 0 if !@isShop
trainer_hair_id = getSplitHairFilenameAndVersionFromID(@worn_hair)[1]
return nil if item.id == trainer_hair_id
return item.price.to_i
end
def getDisplayPrice(item, selling = nil)
trainerStyleID = getSplitHairFilenameAndVersionFromID(@worn_hair)[1]
return "-" if item.id == trainerStyleID
super
end
def getCurrentHairVersion()
begin
return getSplitHairFilenameAndVersionFromID($Trainer.hair)[0]
rescue
return 1
end
end
def getCurrentHairId(itemId)
return getFullHairId(itemId, @version)
end
def getName(item)
echoln $Trainer.hair
return item.id
end
def getDescription(item)
return DEFAULT_DESCRIPTION if !item.description
return item.description
end
def getItemIcon(item)
return Settings::BACK_ITEM_ICON_PATH if !item
return getOverworldHatFilename(item.id)
end
def updateTrainerPreview(item, previewWindow)
item = @previous_item if !item
item = @previous_item if item.is_a?(Symbol)
@previous_item = find_first_item() if !item.is_a?(Symbol)
displayed_hat = @hat_visible ? @worn_hat : nil
displayed_hat2 = @hat_visible ? @worn_hat2 : nil
previewWindow.hat = displayed_hat
previewWindow.hat2 = displayed_hat2
$Trainer.hat = displayed_hat
$Trainer.hat2 = displayed_hat2
itemId = getCurrentHairId(item.id)
previewWindow.hair = itemId
$Trainer.hair = itemId
pbRefreshSceneMap
previewWindow.updatePreview()
end
def addItem(item)
itemId = getCurrentHairId(item.id)
obtainNewHairstyle(itemId)
@worn_hair = itemId
end
def get_current_clothes()
return $Trainer.hair
end
def putOnOutfit(item)
itemFullId = getCurrentHairId(item.id)
putOnHair(item.id, @version)
@worn_hair = itemFullId
end
def reset_player_clothes()
# can change hair color for free if not changing the style
if getVersionFromFullID(@worn_hair) != @version
worn_id = getSimplifiedHairIdFromFullID(@worn_hair)
if getSimplifiedHairIdFromFullID($Trainer.hair) == worn_id
@worn_hair = getFullHairId(worn_id,@version)
end
end
$Trainer.hair = @worn_hair
$Trainer.hat = @worn_hat
$Trainer.hat2 = @worn_hat2
end
def get_unlocked_items_list()
return $Trainer.unlocked_hairstyles
end
def getSpecialItemCaption(specialType)
case specialType
when :SWAP_COLOR
return "Swap Color"
end
return nil
end
def getSpecialItemBaseColor(specialType)
case specialType
when :SWAP_COLOR
return MessageConfig::BLUE_TEXT_MAIN_COLOR
end
return nil
end
def getSpecialItemShadowColor(specialType)
case specialType
when :SWAP_COLOR
return MessageConfig::BLUE_TEXT_SHADOW_COLOR
end
return nil
end
def getSpecialItemDescription(specialType)
return "Swap to the next base hair color."
end
def doSpecialItemAction(specialType)
switchVersion(nil,1)
end
def currentVersionExists?(item)
hairId = getCurrentHairId(item.id)
filename = getOverworldHairFilename(hairId)
return pbResolveBitmap(filename)
end
end

View File

@@ -0,0 +1,68 @@
class HairShopPresenter < PokemonMartScreen
def pbChooseBuyItem
end
def initialize(scene, stock, adapter = nil, versions=false)
super(scene,stock,adapter)
@use_versions = versions
end
def pbBuyScreen
@scene.pbStartBuyScene(@stock, @adapter)
item = nil
loop do
item = @scene.pbChooseBuyItem
break if !item
if !@adapter.isShop?
if pbConfirm(_INTL("Would you like to purchase {1}?", item.name))
@adapter.putOnOutfit(item)
@scene.pbEndBuyScene
return
end
next
end
itemname = @adapter.getDisplayName(item)
price = @adapter.getPrice(item)
echoln price
if !price.is_a?(Integer)
#@adapter.switchVersion(item,1)
pbDisplayPaused(_INTL("This is your current hairstyle!"))
next
end
if @adapter.getMoney < price
pbDisplayPaused(_INTL("You don't have enough money."))
next
end
if !pbConfirm(_INTL("Certainly. You want {1}. That will be ${2}. OK?",
itemname, price.to_s_formatted))
next
end
quantity = 1
if @adapter.getMoney < price
pbDisplayPaused(_INTL("You don't have enough money."))
next
end
added = 0
@adapter.setMoney(@adapter.getMoney - price)
@stock.compact!
pbDisplayPaused(_INTL("Here you are! Thank you!")) { pbSEPlay("Mart buy item") }
@adapter.addItem(item)
#break
end
@scene.pbEndBuyScene
end
def isWornItem?(item)
super
end
end

View File

@@ -0,0 +1,110 @@
# frozen_string_literal: true
class HatShopView < ClothesShopView
def initialize(currency_name = "Money")
@currency_name = currency_name
end
def pbStartBuyOrSellScene(buying, stock, adapter)
super(buying, stock, adapter)
if !@adapter.isShop?
@sprites["hatLayer_selected1"] = IconSprite.new(0, 0, @viewport)
@sprites["hatLayer_selected2"] = IconSprite.new(0, 0, @viewport)
@sprites["hatLayer_selected1"].setBitmap("Graphics/Pictures/Outfits/hatLayer_selected1")
@sprites["hatLayer_selected2"].setBitmap("Graphics/Pictures/Outfits/hatLayer_selected2")
updateSelectedLayerGraphicsVisibility
@sprites["wornHat_layer1"] = IconSprite.new(25, 200, @viewport)
@sprites["wornHat_layer2"] = IconSprite.new(95, 200, @viewport)
displayLayerIcons
end
end
def switchItemVersion(itemwindow)
@adapter.switchVersion(itemwindow.item, 1)
new_selected_hat = @adapter.is_secondary_hat ? $Trainer.hat2 : $Trainer.hat
select_specific_item(new_selected_hat,true)
updateTrainerPreview()
end
def onSpecialActionTrigger(itemwindow)
#@adapter.doSpecialItemAction(itemwindow.item)
#updateTrainerPreview()
return @stock[itemwindow.index]
end
def handleHatlessLayerIcons(selected_item)
other_hat = @adapter.is_secondary_hat ? $Trainer.hat : $Trainer.hat2
if !selected_item.is_a?(Hat)
if @adapter.is_secondary_hat
@sprites["wornHat_layer2"].bitmap=nil
else
@sprites["wornHat_layer1"].bitmap=nil
end
end
if !other_hat.is_a?(Hat)
if @adapter.is_secondary_hat
@sprites["wornHat_layer1"].bitmap=nil
else
@sprites["wornHat_layer2"].bitmap=nil
end
end
end
def displayLayerIcons(selected_item=nil)
handleHatlessLayerIcons(selected_item)
hat1Filename = getOverworldHatFilename($Trainer.hat)
hat2Filename = getOverworldHatFilename($Trainer.hat2)
hat_color_shift = $Trainer.dyed_hats[$Trainer.hat]
hat2_color_shift = $Trainer.dyed_hats[$Trainer.hat2]
hatBitmapWrapper = AnimatedBitmap.new(hat1Filename, hat_color_shift) if pbResolveBitmap(hat1Filename)
hat2BitmapWrapper = AnimatedBitmap.new(hat2Filename, hat2_color_shift) if pbResolveBitmap(hat2Filename)
@sprites["wornHat_layer1"].bitmap = hatBitmapWrapper.bitmap if hatBitmapWrapper
@sprites["wornHat_layer2"].bitmap = hat2BitmapWrapper.bitmap if hat2BitmapWrapper
frame_width=80
frame_height=80
@sprites["wornHat_layer1"].src_rect.set(0, 0, frame_width, frame_height) if hatBitmapWrapper
@sprites["wornHat_layer2"].src_rect.set(0, 0, frame_width, frame_height) if hat2BitmapWrapper
end
def updateSelectedLayerGraphicsVisibility()
@sprites["hatLayer_selected1"].visible = !@adapter.is_secondary_hat
@sprites["hatLayer_selected2"].visible = @adapter.is_secondary_hat
end
def displayNewItem(itemwindow)
item = itemwindow.item
if item
if item.is_a?(Symbol)
description = @adapter.getSpecialItemDescription(itemwindow.item)
else
description = @adapter.getDescription(itemwindow.item)
end
@adapter.updateTrainerPreview(itemwindow.item, @sprites["trainerPreview"])
displayLayerIcons(item)
else
description = _INTL("Quit.")
end
@sprites["itemtextwindow"].text = description
end
def updateTrainerPreview()
super
updateSelectedLayerGraphicsVisibility
end
end

View File

@@ -0,0 +1,230 @@
class HatsMartAdapter < OutfitsMartAdapter
attr_accessor :worn_clothes
attr_accessor :worn_clothes2
DEFAULT_NAME = "[unknown]"
DEFAULT_DESCRIPTION = "A headgear that trainers can wear."
def initialize(stock = nil, isShop = nil, isSecondaryHat = false)
super(stock,isShop,isSecondaryHat)
@worn_clothes = $Trainer.hat
@worn_clothes2 = $Trainer.hat2
@second_hat_visible = true
end
#Used in shops only
def toggleSecondHat()
@second_hat_visible = !@second_hat_visible
$Trainer.hat2 = @second_hat_visible ? @worn_clothes2 : nil
end
def toggleEvent(item)
if isShop?
toggleSecondHat
else
$Trainer.set_hat(nil,@is_secondary_hat)
@worn_clothes = nil
end
end
def list_regional_set_items()
return list_regional_hats
end
def list_city_exclusive_items
return list_city_exclusive_hats
end
def set_secondary_hat(value)
@is_secondary_hat = value
end
def is_wearing_clothes(outfit_id)
return outfit_id == @worn_clothes || outfit_id == @worn_clothes2
end
def toggleText()
return
# return if @isShop
# toggleKey = "D"#getMappedKeyFor(Input::SPECIAL)
# return "Remove hat: #{toggleKey}"
end
def switchVersion(item,delta=1)
pbSEPlay("GUI storage put down", 80, 100)
return toggleSecondHat if isShop?
@is_secondary_hat = !@is_secondary_hat
end
def getName(item)
return item.id
end
def getDescription(item)
return DEFAULT_DESCRIPTION if !item.description
return item.description
end
def getItemIcon(item)
return Settings::BACK_ITEM_ICON_PATH if !item
return getOverworldHatFilename(item.id)
end
def updateTrainerPreview(item, previewWindow)
if item.is_a?(Outfit)
hat1 = @is_secondary_hat ? get_hat_by_id($Trainer.hat) : item
hat2 = @is_secondary_hat ? item : get_hat_by_id($Trainer.hat2)
previewWindow.set_hat(hat1.id,false) if hat1
previewWindow.set_hat(hat2.id,true) if hat2
previewWindow.set_hat(nil,true) if !@second_hat_visible #for toggling in shops
hat1_color=0
hat2_color=0
hat1_color = $Trainer.dyed_hats[hat1.id] if hat1 && $Trainer.dyed_hats.include?(hat1.id)
hat2_color = $Trainer.dyed_hats[hat2.id] if hat2 && $Trainer.dyed_hats.include?(hat2.id)
previewWindow.hat_color = hat1_color
previewWindow.hat2_color = hat2_color
$Trainer.hat = hat1&.id
$Trainer.hat2 = hat2&.id
$Trainer.hat_color = hat1_color
$Trainer.hat2_color = hat2_color
else
$Trainer.set_hat(nil,@is_secondary_hat)
previewWindow.set_hat(nil,@is_secondary_hat)
end
pbRefreshSceneMap
previewWindow.updatePreview()
end
def get_dye_color(item_id)
return if !item_id
return 0 if isShop?
$Trainer.dyed_hats= {} if ! $Trainer.dyed_hats
if $Trainer.dyed_hats.include?(item_id)
return $Trainer.dyed_hats[item_id]
end
return 0
end
def set_dye_color(item,previewWindow,is_secondary_hat=false)
return if !item
if !isShop?
else
$Trainer.set_hat_color(0,is_secondary_hat)
previewWindow.hat_color=0
end
end
# def set_dye_color(item,previewWindow,is_secondary_hat=false)
# return if !item
# if !isShop?
# $Trainer.dyed_hats= {} if !$Trainer.dyed_hats
#
# echoln item.id
# echoln $Trainer.dyed_hats.include?(item.id)
# echoln $Trainer.dyed_hats[item.id]
#
# if $Trainer.dyed_hats.include?(item.id)
# dye_color = $Trainer.dyed_hats[item.id]
# $Trainer.set_hat_color(dye_color,is_secondary_hat)
# previewWindow.hat_color = dye_color
# else
# $Trainer.set_hat_color(0,is_secondary_hat)
# previewWindow.hat_color=0
# end
# #echoln $Trainer.dyed_hats
# else
# $Trainer.set_hat_color(0,is_secondary_hat)
# previewWindow.hat_color=0
# end
# end
def addItem(item)
return unless item.is_a?(Outfit)
changed_clothes = obtainHat(item.id,@is_secondary_hat)
if changed_clothes
@worn_clothes = item.id
end
end
def get_current_clothes()
return $Trainer.hat(@is_secondary_hat)
end
def player_changed_clothes?()
echoln("Trainer hat: #{$Trainer.hat}, Worn hat: #{@worn_clothes}")
echoln("Trainer hat2: #{$Trainer.hat2}, Worn hat2: #{@worn_clothes2}")
$Trainer.hat != @worn_clothes || $Trainer.hat2 != @worn_clothes2
end
def putOnSelectedOutfit()
putOnHat($Trainer.hat,true,false) if $Trainer.hat
putOnHat($Trainer.hat2,true,true) if $Trainer.hat2
@worn_clothes = $Trainer.hat
@worn_clothes2 = $Trainer.hat2
playOutfitChangeAnimation()
pbMessage(_INTL("You put on the hat(s)!\\wtnp[30]"))
end
def putOnOutfit(item)
return unless item.is_a?(Outfit)
putOnHat(item.id,false,@is_secondary_hat)
@worn_clothes = item.id
end
def reset_player_clothes()
$Trainer.set_hat(@worn_clothes,false)
$Trainer.set_hat(@worn_clothes2,true)
$Trainer.set_hat_color($Trainer.dyed_hats[@worn_clothes],false) if $Trainer.dyed_hats && $Trainer.dyed_hats[@worn_clothes]
$Trainer.set_hat_color($Trainer.dyed_hats[@worn_clothes2],true) if $Trainer.dyed_hats && $Trainer.dyed_hats[@worn_clothes2]
end
def get_unlocked_items_list()
return $Trainer.unlocked_hats
end
def getSpecialItemCaption(specialType)
case specialType
when :REMOVE_HAT
return "Remove hat"
end
return nil
end
def getSpecialItemBaseColor(specialType)
case specialType
when :REMOVE_HAT
return MessageConfig::BLUE_TEXT_MAIN_COLOR
end
return nil
end
def getSpecialItemShadowColor(specialType)
case specialType
when :REMOVE_HAT
return MessageConfig::BLUE_TEXT_SHADOW_COLOR
end
return nil
end
def getSpecialItemDescription(specialType)
hair_situation = !$Trainer.hair || getSimplifiedHairIdFromFullID($Trainer.hair) == HAIR_BALD ? "bald head" : "fabulous hair"
return "Go without a hat and show off your #{hair_situation}!"
end
def doSpecialItemAction(specialType,item=nil)
toggleEvent(item)
end
end

View File

@@ -0,0 +1,160 @@
class HairStyleSelectionMenuView
attr_accessor :name_sprite
attr_accessor :viewport
attr_accessor :sprites
attr_accessor :textValues
OPTIONS_START_Y = 66
CURSOR_Y_MARGIN = 50
CURSOR_X_MARGIN = 76
CHECKMARK_Y_MARGIN = 20
CHECKMARK_WIDTH = 50
OPTIONS_LABEL_X = 50
OPTIONS_LABEL_WIDTH = 100
OPTIONS_VALUE_X = 194
SELECTOR_X = 120
SELECTOR_STAGGER_OFFSET=26
ARROW_LEFT_X_POSITION = 75
ARROW_RIGHT_X_POSITION = 275
ARROWS_Y_OFFSET = 10#20
CONFIRM_X = 296
CONFIRM_Y= 322
STAGGER_OFFSET_1 = 26
STAGGER_OFFSET_2 = 50
def initialize
@presenter = HairstyleSelectionMenuPresenter.new(self)
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@sprites = {}
@textValues={}
@max_index=5
end
def init_graphics()
@sprites["bg"] = IconSprite.new(@viewport)
#@sprites["bg"].setBitmap("Graphics/Pictures/trainer_application_form")
@sprites["bg"].setBitmap("")
@sprites["select"] = IconSprite.new(@viewport)
@sprites["select"].setBitmap("Graphics/Pictures/cc_selection_box")
@sprites["select"].x = get_cursor_x_position(0)#OPTIONS_LABEL_X + OPTIONS_LABEL_WIDTH + CURSOR_X_MARGIN
@sprites["select"].y = OPTIONS_START_Y
@sprites["select"].visible = true
@sprites["leftarrow"] = AnimatedSprite.new("Graphics/Pictures/leftarrow", 8, 40, 28, 2, @viewport)
@sprites["leftarrow"].x = ARROW_LEFT_X_POSITION
@sprites["leftarrow"].y = 0
@sprites["leftarrow"].visible = false
@sprites["leftarrow"].play
@sprites["rightarrow"] = AnimatedSprite.new("Graphics/Pictures/rightarrow", 8, 40, 28, 2, @viewport)
@sprites["rightarrow"].x = ARROW_RIGHT_X_POSITION
@sprites["rightarrow"].y = 0
@sprites["rightarrow"].visible = false
@sprites["rightarrow"].play
end
def setMaxIndex(maxIndex)
@max_index=maxIndex
end
def init_labels()
Kernel.pbDisplayText("Confirm", (CONFIRM_X+CURSOR_X_MARGIN), CONFIRM_Y)
end
def start
init_graphics()
init_labels()
@presenter.main()
end
def get_cursor_y_position(index)
return CONFIRM_Y if index == @max_index
return index * CURSOR_Y_MARGIN + OPTIONS_START_Y
end
def get_cursor_x_position(index)
return CONFIRM_X if index == @max_index
return SELECTOR_X + getTextBoxStaggerOffset(index)
end
def get_value_x_position(index)
return (OPTIONS_VALUE_X + getTextBoxStaggerOffset(index))
end
def getTextBoxStaggerOffset(index)
case index
when 1
return STAGGER_OFFSET_1
when 2
return STAGGER_OFFSET_2
when 3
return STAGGER_OFFSET_1
end
return 0
end
def showSideArrows(y_index)
y_position = get_cursor_y_position(y_index)
@sprites["rightarrow"].y=y_position+ARROWS_Y_OFFSET
@sprites["leftarrow"].y=y_position+ARROWS_Y_OFFSET
@sprites["leftarrow"].x=getTextBoxStaggerOffset(y_index)+ARROW_LEFT_X_POSITION
@sprites["rightarrow"].x= getTextBoxStaggerOffset(y_index)+ARROW_RIGHT_X_POSITION
@sprites["rightarrow"].visible=true
@sprites["leftarrow"].visible=true
end
def hideSideArrows()
@sprites["rightarrow"].visible=false
@sprites["leftarrow"].visible=false
end
def displayText(spriteId,text,y_index)
@textValues[spriteId].dispose if @textValues[spriteId]
yposition = get_cursor_y_position(y_index)
xposition = get_value_x_position(y_index)
baseColor= baseColor ? baseColor : Color.new(72,72,72)
shadowColor= shadowColor ? shadowColor : Color.new(160,160,160)
@textValues[spriteId] = BitmapSprite.new(Graphics.width,Graphics.height,@viewport)
text1=_INTL(text)
textPosition=[
[text1,xposition,yposition,2,baseColor,shadowColor],
]
pbSetSystemFont(@textValues[spriteId].bitmap)
pbDrawTextPositions(@textValues[spriteId].bitmap,textPosition)
end
def updateGraphics()
Graphics.update
Input.update
if @sprites
@sprites["rightarrow"].update
@sprites["leftarrow"].update
end
end
end

View File

@@ -0,0 +1,187 @@
class HairstyleSelectionMenuPresenter
attr_accessor :options
attr_reader :current_index
OPTION_STYLE = 'Hairstyle'
OPTION_BASE_COLOR = "Base color"
OPTION_DYE = "Dye"
HAIR_COLOR_NAMES = ["Blonde", "Light Brown", "Dark Brown", "Black"]
HAIR_COLOR_IDS = [1, 2, 3, 4]
#ids for displayed text sprites
STYLE_TEXT_ID = "style"
BASECOLOR_TEXT_ID = "baseCplor"
DYE_TEXT_ID = "dye"
def initialize(view)
@view = view
@hairstyle_full_id = $Trainer.hair
hairstyle_split = getSplitHairFilenameAndVersionFromID(@hairstyle_full_id)
@hairstyle = hairstyle_split[0] if hairstyle_split[0]
@hair_version = hairstyle_split[1] if hairstyle_split[1]
@hairColor = $Trainer.hair_color
@available_styles= $Trainer.unlocked_hairstyles
@selected_hairstyle_index = 0
echoln @available_styles
@options = [OPTION_STYLE, OPTION_BASE_COLOR, OPTION_DYE]
@trainerPreview = TrainerClothesPreview.new(300, 80, false)
@trainerPreview.show()
@closed = false
@current_index = 0
@view.setMaxIndex(@options.length - 1)
end
def main()
pbSEPlay("GUI naming tab swap start", 80, 100)
@current_index = 0
loop do
@view.updateGraphics()
if Input.trigger?(Input::DOWN)
@current_index = move_menu_vertical(1)
elsif Input.trigger?(Input::UP)
@current_index = move_menu_vertical(-1)
elsif Input.trigger?(Input::RIGHT)
move_menu_horizontal(@current_index, 1)
elsif Input.trigger?(Input::LEFT)
move_menu_horizontal(@current_index, -1)
elsif Input.trigger?(Input::ACTION) || Input.trigger?(Input::USE)
action_button_pressed(@current_index)
end
break if @closed
end
end
def updateTrainerPreview
@trainerPreview.resetOutfits
@trainerPreview.updatePreview
end
def action_button_pressed(current_index)
pbSEPlay("GUI save choice", 80, 100)
@current_index = @options.length - 1
update_cursor(@current_index)
end
def getDefaultName()
return DEFAULT_NAMES[@gender]
end
def applyAllSelectedValues
$Trainer.hair = getFullHairId(@hairstyle,@hair_version)
$Trainer.hair_color = @hairColor
end
def getOptionIndex(option_name)
i = 0
for option in @options
return i if option == option_name
i += 1
end
return -1
end
#VERTICAL NAVIGATION
def move_menu_vertical(offset)
pbSEPlay("GUI sel decision", 80, 100)
@current_index += offset
@current_index = 0 if @current_index > @options.length - 1
@current_index = @options.length - 1 if @current_index <= -1
update_cursor(@current_index)
return @current_index
end
def update_cursor(index)
@view.sprites["select"].y = @view.get_cursor_y_position(index)
@view.sprites["select"].x = @view.get_cursor_x_position(index)
set_custom_cursor(index)
end
def close_menu
@trainerPreview.erase()
Kernel.pbClearNumber()
Kernel.pbClearText()
pbDisposeSpriteHash(@view.sprites)
pbDisposeSpriteHash(@view.textValues)
@closed = true
end
def set_custom_cursor(index)
# selected_option = @options[index]
# case selected_option
# when OPTION_GENDER
# @view.showSideArrows(index)
# when OPTION_AGE
# @view.showSideArrows(index)
# when OPTION_HAIR
# @view.showSideArrows(index)
# when OPTION_SKIN
# @view.showSideArrows(index)
# else
# @view.hideSideArrows
# end
end
#HORIZONTAL NAVIGATION
def move_menu_horizontal(current_index, incr)
pbSEPlay("GUI sel cursor", 80, 100)
selected_option = @options[current_index]
case selected_option
when OPTION_STYLE then
setHairstyle(@selected_hairstyle_index,incr)
end
# case selected_option
# when OPTION_GENDER then
# setGender(current_index, incr)
# when OPTION_HAIR then
# setHairColor(current_index, incr)
# when OPTION_SKIN then
# setSkinColor(current_index, incr)
# when OPTION_AGE then
# setAge(current_index, incr)
# end
updateTrainerPreview()
end
def setHairstyle(current_index, incr)
@selected_hairstyle_index += incr
@selected_hairstyle_index = 0 if @selected_hairstyle_index > @available_styles.length
@selected_hairstyle_index = @available_styles.length-1 if @selected_hairstyle_index < 0
@hairstyle = @available_styles[@selected_hairstyle_index]
applyHair()
echoln @hairstyle
echoln "hairstyle: #{@hairstyle}, full list: #{@available_styles}, index: #{current_index}"
@view.displayText(STYLE_TEXT_ID, @hairstyle, @selected_hairstyle_index)
end
def setBaseColor(current_index, incr)
max_id = HAIR_COLOR_IDS.length - 1
@hairColor += incr
@hairColor = 0 if @hairColor > max_id
@hairColor = max_id if @hairColor <= -1
applyHair()
@view.displayText(BASECOLOR_TEXT_ID, HAIR_COLOR_NAMES[@hairColor], current_index)
end
def applyHair()
hairstyle = @hairstyle
hair_version =@hair_version
hairId = getFullHairId(hairstyle,hair_version)
$Trainer.hair = hairId
end
end

View File

@@ -0,0 +1,126 @@
#Naked sprites
BASE_FOLDER = "base"
BASE_OVERWORLD_FOLDER = "overworld"
BASE_TRAINER_FOLDER = "trainer"
def getBaseOverworldSpriteFilename(action = "walk", skinTone = "default")
base_path = Settings::PLAYER_GRAPHICS_FOLDER + BASE_FOLDER + "/" + BASE_OVERWORLD_FOLDER
dynamic_path = _INTL("/{1}/{2}_{1}", skinTone, action)
full_path = base_path + dynamic_path
return full_path if pbResolveBitmap(full_path)
return getBaseOverworldSpriteFilename(action) if skinTone != "default" #try again with default skintone
return nil
end
def getBaseTrainerSpriteFilename(skinTone = "default")
base_path = Settings::PLAYER_GRAPHICS_FOLDER + BASE_FOLDER + "/" + BASE_TRAINER_FOLDER
dynamic_path = _INTL("/{1}_{2}", BASE_TRAINER_FOLDER, skinTone)
full_path = base_path + dynamic_path
return full_path if pbResolveBitmap(full_path)
return getBaseTrainerSpriteFilename() #default skintone
end
### OUTFIT #
def get_clothes_sets_list_path()
return Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_CLOTHES_FOLDER
end
def getOverworldOutfitFilename(outfit_id, action="walk")
base_path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_CLOTHES_FOLDER
dynamic_path = _INTL("/{1}/", outfit_id)
filename = _INTL(Settings::PLAYER_CLOTHES_FOLDER + "_{1}_{2}", action, outfit_id)
full_path = base_path + dynamic_path + filename
#echoln full_path
return full_path
end
def getTrainerSpriteOutfitFilename(outfit_id)
return getOverworldOutfitFilename(outfit_id, BASE_TRAINER_FOLDER)
end
#### HAIR
def get_hair_sets_list_path()
return Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_HAIR_FOLDER
end
def getSimplifiedHairIdFromFullID(full_id)
split_id = getSplitHairFilenameAndVersionFromID(full_id)
return split_id[1] if split_id.length > 1
return ""
end
def getVersionFromFullID(full_id)
split_id = getSplitHairFilenameAndVersionFromID(full_id)
return split_id[0]
end
# Input: 1_red
# Output: ["1","red"]
def getSplitHairFilenameAndVersionFromID(hairstyle_id)
return "" if !hairstyle_id
hairstyle_id= hairstyle_id.to_s
return hairstyle_id.split("_")
end
def getFullHairId(hairstyle,version)
return _INTL("{1}_{2}",version,hairstyle)
end
def getOverworldHairFilename(hairstyle_id)
hairstyle_split = getSplitHairFilenameAndVersionFromID(hairstyle_id)
name= hairstyle_split[-1]
version= hairstyle_split[-2]
base_path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_HAIR_FOLDER
dynamic_path = _INTL("/{1}/", name)
filename = _INTL(Settings::PLAYER_HAIR_FOLDER + "_{1}_{2}",version, name)
full_path = base_path + dynamic_path + filename
return full_path
end
def getTrainerSpriteHairFilename(hairstyle_id)
return "" if !hairstyle_id
hairstyle_id= hairstyle_id.to_s
hairstyle_split= hairstyle_id.split("_")
name= hairstyle_split[-1]
version= hairstyle_split[-2]
base_path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_HAIR_FOLDER
dynamic_path = _INTL("/{1}/", name)
filename = _INTL(Settings::PLAYER_HAIR_FOLDER + "_trainer_{1}_{2}",version, name)
full_path = base_path + dynamic_path + filename
return full_path
end
#### HATS
#
def get_hats_sets_list_path()
return Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_HAT_FOLDER
end
def getOverworldHatFilename(hat_id)
base_path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_HAT_FOLDER
dynamic_path = _INTL("/{1}/", hat_id)
filename = _INTL(Settings::PLAYER_HAT_FOLDER + "_{1}", hat_id)
full_path = base_path + dynamic_path + filename
return full_path
end
def getTrainerSpriteHatFilename(hat_id)
base_path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_HAT_FOLDER
dynamic_path = _INTL("/{1}/", hat_id)
filename = _INTL(Settings::PLAYER_HAT_FOLDER + "_trainer_{1}", hat_id)
full_path = base_path + dynamic_path + filename
return full_path
end
def getTrainerSpriteBallFilename(pokeball)
base_path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_BALL_FOLDER
return base_path + "/" + pokeball.to_s
end

View File

@@ -0,0 +1,412 @@
def obtainNewHat(outfit_id)
return obtainHat(outfit_id)
end
def obtainNewClothes(outfit_id)
return obtainClothes(outfit_id)
end
def obtainHat(outfit_id,secondary=false)
echoln "obtained new hat: " + outfit_id
outfit = get_hat_by_id(outfit_id)
if !outfit
pbMessage(_INTL("The hat #{outfit_id} is invalid."))
return
end
$Trainer.unlocked_hats << outfit_id if !$Trainer.unlocked_hats.include?(outfit_id)
obtainOutfitMessage(outfit)
if pbConfirmMessage("Would you like to put it on right now?")
putOnHat(outfit_id, false, false) if !secondary
putOnHat(outfit_id, false, true) if secondary
return true
end
return false
end
def obtainClothes(outfit_id)
echoln "obtained new clothes: " + outfit_id
outfit = get_clothes_by_id(outfit_id)
if !outfit
pbMessage(_INTL("The clothes #{outfit_id} are invalid."))
return
end
return if !outfit
$Trainer.unlocked_clothes << outfit_id if !$Trainer.unlocked_clothes.include?(outfit_id)
obtainOutfitMessage(outfit)
if pbConfirmMessage("Would you like to put it on right now?")
putOnClothes(outfit_id)
return true
end
return false
end
def obtainNewHairstyle(full_outfit_id)
split_outfit_id = getSplitHairFilenameAndVersionFromID(full_outfit_id)
hairstyle_id = split_outfit_id[1]
hairstyle = get_hair_by_id(hairstyle_id)
musical_effect = "Key item get"
pbMessage(_INTL("\\me[{1}]Your hairstyle was changed to \\c[1]{2}\\c[0] hairstyle!\\wtnp[30]", musical_effect, hairstyle.name))
return true
end
def putOnClothes(outfit_id, silent = false)
$Trainer.dyed_clothes= {} if ! $Trainer.dyed_clothes
$Trainer.last_worn_outfit = $Trainer.clothes
outfit = get_clothes_by_id(outfit_id)
$Trainer.clothes = outfit_id
dye_color = $Trainer.dyed_clothes[outfit_id]
if dye_color
$Trainer.clothes_color = dye_color
else
$Trainer.clothes_color = nil
end
$game_map.update
refreshPlayerOutfit()
putOnOutfitMessage(outfit) if !silent
end
def putOnHat(outfit_id, silent = false, is_secondary=false)
$Trainer.dyed_hats= {} if ! $Trainer.dyed_hats
$Trainer.set_last_worn_hat($Trainer.hat,is_secondary)
outfit = get_hat_by_id(outfit_id)
$Trainer.set_hat(outfit_id,is_secondary)
dye_color = $Trainer.dyed_hats[outfit_id]
if dye_color
$Trainer.hat_color = dye_color if !is_secondary
$Trainer.hat2_color = dye_color if is_secondary
else
$Trainer.hat_color = nil if !is_secondary
$Trainer.hat2_color = nil if is_secondary
end
$game_map.refreshPlayerOutfit()
putOnOutfitMessage(outfit) if !silent
end
def putOnHairFullId(full_outfit_id)
outfit_id = getSplitHairFilenameAndVersionFromID(full_outfit_id)[1]
outfit = get_hair_by_id(outfit_id)
$Trainer.hair = full_outfit_id
$game_map.update
refreshPlayerOutfit()
putOnOutfitMessage(outfit)
end
def putOnHair(outfit_id, version)
full_id = getFullHairId(outfit_id, version)
putOnHairFullId(full_id)
#outfit = get_hair_by_id(outfit_id)
#$Trainer.hair =
#putOnOutfitMessage(outfit)
end
def showOutfitPicture(outfit)
begin
outfitPath = outfit.trainer_sprite_path()
viewport = Viewport.new(Graphics.width / 4, 0, Graphics.width / 2, Graphics.height)
bg_sprite = Sprite.new(viewport)
outfit_sprite = Sprite.new(viewport)
outfit_bitmap = AnimatedBitmap.new(outfitPath) if pbResolveBitmap(outfitPath)
bg_bitmap = AnimatedBitmap.new("Graphics/Pictures/Outfits/obtain_bg")
outfit_sprite.bitmap = outfit_bitmap.bitmap
bg_sprite.bitmap = bg_bitmap.bitmap
# bitmap = AnimatedBitmap.new("Graphics/Pictures/Outfits/obtain_bg")
outfit_sprite.x = -50
outfit_sprite.y = 50
outfit_sprite.y -= 120 if outfit.type == :CLOTHES
# outfit_sprite.y = Graphics.height/2
outfit_sprite.zoom_x = 2
outfit_sprite.zoom_y = 2
bg_sprite.x = 0
viewport.z = 99999
# bg_sprite.y = Graphics.height/2
return viewport
rescue
#ignore
end
end
def obtainOutfitMessage(outfit)
pictureViewport = showOutfitPicture(outfit)
musical_effect = "Key item get"
pbMessage(_INTL("\\me[{1}]You obtained a \\c[1]{2}\\c[0]!\\wtnp[30]", musical_effect, outfit.name))
pictureViewport.dispose if pictureViewport
end
def putOnOutfitMessage(outfit)
playOutfitChangeAnimation()
outfitName = outfit.name == "" ? outfit.id : outfit.name
pbMessage(_INTL("You put on the \\c[1]{1}\\c[0]!\\wtnp[30]", outfitName))
end
def refreshPlayerOutfit()
return if !$scene.spritesetGlobal
$scene.spritesetGlobal.playersprite.refreshOutfit()
end
def findLastHairVersion(hairId)
possible_versions = (1..9).to_a
last_version = 0
possible_versions.each { |version|
hair_id = getFullHairId(hairId, version)
echoln hair_id
echoln pbResolveBitmap(getOverworldHairFilename(hair_id))
if pbResolveBitmap(getOverworldHairFilename(hair_id))
last_version = version
else
return last_version
end
}
return last_version
end
def isWearingClothes(outfitId)
return $Trainer.clothes == outfitId
end
def isWearingHat(outfitId)
return $Trainer.hat == outfitId || $Trainer.hat2 == outfitId
end
def isWearingHairstyle(outfitId, version = nil)
current_hair_split_id = getSplitHairFilenameAndVersionFromID($Trainer.hair)
current_id = current_hair_split_id.length >= 1 ? current_hair_split_id[1] : nil
current_version = current_hair_split_id[0]
if version
return outfitId == current_id && version == current_version
end
return outfitId == current_id
end
#Some game switches need to be on/off depending on the outfit that the player is wearing,
# this is called every time you change outfit to make sure that they're always updated correctly
def updateOutfitSwitches(refresh_map = true)
$game_switches[WEARING_ROCKET_OUTFIT] = isWearingTeamRocketOutfit()
#$game_map.update
#$scene.reset_map(true) if refresh_map
#$scene.reset_map(false)
end
def getDefaultClothes()
gender = pbGet(VAR_TRAINER_GENDER)
if gender == GENDER_MALE
return DEFAULT_OUTFIT_MALE
end
return DEFAULT_OUTFIT_FEMALE
end
def hasClothes?(outfit_id)
return $Trainer.unlocked_clothes.include?(outfit_id)
end
def hasHat?(outfit_id)
return $Trainer.unlocked_hats.include?(outfit_id)
end
def getOutfitForPokemon(pokemonSpecies)
possible_clothes = []
possible_hats = []
body_pokemon_id = get_body_species_from_symbol(pokemonSpecies).to_s.downcase
head_pokemon_id = get_head_species_from_symbol(pokemonSpecies).to_s.downcase
body_pokemon_tag = "pokemon-#{body_pokemon_id}"
head_pokemon_tag = "pokemon-#{head_pokemon_id}"
possible_hats += search_hats([body_pokemon_tag])
possible_hats += search_hats([head_pokemon_tag])
possible_clothes += search_clothes([body_pokemon_tag])
possible_clothes += search_clothes([head_pokemon_tag])
if isFusion(getDexNumberForSpecies(pokemonSpecies))
possible_hats += search_hats(["pokemon-fused"], [], false)
possible_clothes += search_clothes(["pokemon-fused"], false)
end
possible_hats = filter_hats_only_not_owned(possible_hats)
possible_clothes = filter_clothes_only_not_owned(possible_clothes)
if !possible_hats.empty?() && !possible_clothes.empty?() #both have values, pick one at random
return [[possible_hats.sample, :HAT], [possible_clothes.sample, :CLOTHES]].sample
elsif !possible_hats.empty?
return [possible_hats.sample, :HAT]
elsif !possible_clothes.empty?
return [possible_clothes.sample, :CLOTHES]
end
return []
end
def hatUnlocked?(hatId)
return $Trainer.unlocked_hats.include?(hatId)
end
def export_current_outfit()
skinTone = $Trainer.skin_tone ? $Trainer.skin_tone : 0
hat = $Trainer.hat ? $Trainer.hat : "nil"
hair_color = $Trainer.hair_color || 0
clothes_color = $Trainer.clothes_color || 0
hat_color = $Trainer.hat_color || 0
exportedString = "TrainerAppearance.new(#{skinTone},\"#{hat}\",\"#{$Trainer.clothes}\",\"#{$Trainer.hair}\",#{hair_color},#{clothes_color},#{hat_color})"
Input.clipboard = exportedString
end
def clearEventCustomAppearance(event_id)
return if !$scene.is_a?(Scene_Map)
event_sprite = $scene.spriteset.character_sprites[@event_id]
for sprite in $scene.spriteset.character_sprites
if sprite.character.id == event_id
event_sprite = sprite
end
end
return if !event_sprite
event_sprite.clearBitmapOverride
end
def setEventAppearance(event_id, trainerAppearance)
return if !$scene.is_a?(Scene_Map)
event_sprite = $scene.spriteset.character_sprites[@event_id]
for sprite in $scene.spriteset.character_sprites
if sprite.character.id == event_id
event_sprite = sprite
end
end
return if !event_sprite
event_sprite.setSpriteToAppearance(trainerAppearance)
end
def getPlayerAppearance()
return TrainerAppearance.new($Trainer.skin_tone,$Trainer.hat,$Trainer.clothes, $Trainer.hair,
$Trainer.hair_color, $Trainer.clothes_color, $Trainer.hat_color)
end
def randomizePlayerOutfitUnlocked()
$Trainer.hat = $Trainer.unlocked_hats.sample
$Trainer.hat2 = $Trainer.unlocked_hats.sample
$Trainer.clothes = $Trainer.unlocked_clothes.sample
dye_hat = rand(2)==0
dye_hat2 = rand(2)==0
dye_clothes = rand(2)==0
dye_hair = rand(2)==0
$Trainer.hat2 = nil if rand(3)==0
$Trainer.hat_color = dye_hat ? rand(255) : 0
$Trainer.hat2_color = dye_hat2 ? rand(255) : 0
$Trainer.clothes_color = dye_clothes ? rand(255) : 0
$Trainer.hair_color = dye_hair ? rand(255) : 0
hair_id = $PokemonGlobal.hairstyles_data.keys.sample
hair_color = [1,2,3,4].sample
$Trainer.hair = getFullHairId(hair_id,hair_color)
end
def convert_letter_to_number(letter, max_number = nil)
return 0 unless letter
base_value = (letter.ord * 31) & 0xFFFFFFFF # Use a prime multiplier to spread values
return base_value unless max_number
return base_value % max_number
end
def generate_appearance_from_name(name)
name_seed_length = 13
max_dye_color=360
seed = name[0, name_seed_length] # Truncate if longer than 8
seed += seed[0, name_seed_length - seed.length] while seed.length < name_seed_length # Repeat first characters if shorter
echoln seed
hats_list = $PokemonGlobal.hats_data.keys
clothes_list = $PokemonGlobal.clothes_data.keys
hairstyles_list = $PokemonGlobal.hairstyles_data.keys
hat = hats_list[convert_letter_to_number(seed[0],hats_list.length)]
hat_color = convert_letter_to_number(seed[1],max_dye_color)
hat2_color = convert_letter_to_number(seed[2],max_dye_color)
hat_color = 0 if convert_letter_to_number(seed[2]) % 2 == 0 #1/2 chance of no dyed hat
hat2 = hats_list[convert_letter_to_number(seed[10],hats_list.length)]
hat2_color = 0 if convert_letter_to_number(seed[11]) % 2 == 0 #1/2 chance of no dyed ha
hat2 = "" if convert_letter_to_number(seed[12]) % 2 == 0 #1/2 chance of no 2nd hat
clothes = clothes_list[convert_letter_to_number(seed[3],clothes_list.length)]
clothes_color = convert_letter_to_number(seed[4],max_dye_color)
clothes_color = 0 if convert_letter_to_number(seed[5]) % 2 == 0 #1/2 chance of no dyed clothes
hair_base = hairstyles_list[convert_letter_to_number(seed[6],hairstyles_list.length)]
hair_number = [1,2,3,4][convert_letter_to_number(seed[7],3)]
echoln "hair_number: #{hair_number}"
hair=getFullHairId(hair_base,hair_number)
hair_color = convert_letter_to_number(seed[8],max_dye_color)
hair_color = 0 if convert_letter_to_number(seed[9]) % 2 == 0 #1/2 chance of no dyed hair
echoln hair_color
echoln clothes_color
echoln hat_color
skin_tone = [1,2,3,4,5,6][convert_letter_to_number(seed[10],5)]
return TrainerAppearance.new(skin_tone,hat,clothes, hair,
hair_color, clothes_color, hat_color,
hat2,hat2_color)
end
def get_random_appearance()
hat = $PokemonGlobal.hats_data.keys.sample
hat2 = $PokemonGlobal.hats_data.keys.sample
hat2 = nil if(rand(3)==0)
clothes = $PokemonGlobal.clothes_data.keys.sample
hat_color = rand(2)==0 ? rand(255) : 0
hat2_color = rand(2)==0 ? rand(255) : 0
clothes_color = rand(2)==0 ? rand(255) : 0
hair_color = rand(2)==0 ? rand(255) : 0
hair_id = $PokemonGlobal.hairstyles_data.keys.sample
hair_color = [1,2,3,4].sample
skin_tone = [1,2,3,4,5,6].sample
hair = getFullHairId(hair_id,hair_color)
return TrainerAppearance.new(skin_tone,hat,clothes, hair,
hair_color, clothes_color, hat_color,hat2)
end
def randomizePlayerOutfit()
$Trainer.hat = $PokemonGlobal.hats_data.keys.sample
$Trainer.hat2 = $PokemonGlobal.hats_data.keys.sample
$Trainer.hat2 = nil if(rand(3)==0)
$Trainer.clothes = $PokemonGlobal.clothes_data.keys.sample
$Trainer.hat_color = rand(2)==0 ? rand(255) : 0
$Trainer.hat2_color = rand(2)==0 ? rand(255) : 0
$Trainer.clothes_color = rand(2)==0 ? rand(255) : 0
$Trainer.hair_color = rand(2)==0 ? rand(255) : 0
hair_id = $PokemonGlobal.hairstyles_data.keys.sample
hair_color = [1,2,3,4].sample
$Trainer.skin_tone = [1,2,3,4,5,6].sample
$Trainer.hair = getFullHairId(hair_id,hair_color)
end
def canPutHatOnPokemon(pokemon)
return !pokemon.egg? && !pokemon.isTripleFusion? && $game_switches[SWITCH_UNLOCKED_POKEMON_HATS]
end

View File

@@ -0,0 +1,19 @@
class Outfit
attr_accessor :id
attr_accessor :name
attr_accessor :description
attr_accessor :tags
attr_accessor :price
def initialize(id, name, description = '',price=0, tags = [])
@id = id
@name = name
@description = description
@tags = tags
@price = price
end
def trainer_sprite_path()
return nil
end
end

View File

@@ -0,0 +1,11 @@
class Clothes < Outfit
attr_accessor :type
def initialize(id, name, description = '',price=0, tags = [])
super
@type = :CLOTHES
end
def trainer_sprite_path()
return getTrainerSpriteOutfitFilename(self.id)
end
end

View File

@@ -0,0 +1,12 @@
class Hairstyle < Outfit
attr_accessor :type
def initialize(id, name, description = '',price=0, tags = [])
super
@type = :HAIR
end
def trainer_sprite_path()
return getTrainerSpriteHairFilename(self.id)
end
end

View File

@@ -0,0 +1,11 @@
class Hat < Outfit
attr_accessor :type
def initialize(id,name,description='',price=0,tags=[])
super
@type = :HAT
end
def trainer_sprite_path()
return getTrainerSpriteHatFilename(self.id)
end
end

View File

@@ -0,0 +1,291 @@
class Player < Trainer
attr_accessor :skin_tone
attr_accessor :clothes
attr_accessor :hat
attr_accessor :hat2
attr_accessor :hair
attr_accessor :hair_color
attr_accessor :hat_color
attr_accessor :hat2_color
attr_accessor :clothes_color
attr_accessor :unlocked_clothes
attr_accessor :unlocked_hats
attr_accessor :unlocked_hairstyles
attr_accessor :unlocked_card_backgrounds
attr_accessor :dyed_hats
attr_accessor :dyed_clothes
attr_accessor :favorite_hat
attr_accessor :favorite_hat2
attr_accessor :favorite_clothes
attr_accessor :last_worn_outfit
attr_accessor :last_worn_hat
attr_accessor :last_worn_hat2
attr_accessor :surfing_pokemon
attr_accessor :card_background
attr_accessor :unlocked_card_backgrounds
attr_accessor :seen_qmarks_sprite
attr_accessor :beat_league
attr_accessor :new_game_plus_unlocked
def last_worn_outfit
if !@last_worn_outfit
if pbGet(VAR_TRAINER_GENDER) == GENDER_MALE
@last_worn_outfit = DEFAULT_OUTFIT_MALE
else
@last_worn_outfit = DEFAULT_OUTFIT_FEMALE
end
end
return @last_worn_outfit
end
def last_worn_hat(is_secondary = false)
return is_secondary ? @last_worn_hat2 : @last_worn_hat
end
def set_last_worn_hat(value, is_secondary = false)
if is_secondary
@last_worn_hat = value
else
@last_worn_hat = value
end
end
def last_worn_hat2
return @last_worn_hat2
end
def outfit=(value)
@outfit = value
end
def favorite_hat(is_secondary = false)
return is_secondary ? @favorite_hat2 : @favorite_hat
end
# todo change to set_favorite_hat(value,is_secondary=false)
def set_favorite_hat(value, is_secondary = false)
if is_secondary
@favorite_hat = value
else
@favorite_hat2 = value
end
end
def hat_color(is_secondary = false)
return is_secondary ? @hat2_color : @hat_color
end
def hat(is_secondary = false)
return is_secondary ? @hat2 : @hat
end
def set_hat(value, is_secondary = false)
if value.is_a?(Symbol)
value = HATS[value].id
end
if is_secondary
@hat2 = value
else
@hat = value
end
refreshPlayerOutfit()
end
# todo : refactor to always use set_hat instead
def hat=(value)
if value.is_a?(Symbol)
value = HATS[value].id
end
@hat = value
refreshPlayerOutfit()
end
# todo : refactor to always use set_hat instead
def hat2=(value)
if value.is_a?(Symbol)
value = HATS[value].id
end
@hat2 = value
refreshPlayerOutfit()
end
def hair=(value)
if value.is_a?(Symbol)
value = HAIRSTYLES[value].id
end
@hair = value
refreshPlayerOutfit()
end
def clothes=(value)
if value.is_a?(Symbol)
value = OUTFITS[value].id
end
@clothes = value
refreshPlayerOutfit()
end
def clothes_color=(value)
@clothes_color = value
$Trainer.dyed_clothes = {} if !$Trainer.dyed_clothes
$Trainer.dyed_clothes[@clothes] = value if value
refreshPlayerOutfit()
end
def set_hat_color(value, is_secondary = false)
if is_secondary
@hat2_color = value
else
@hat_color = value
end
$Trainer.dyed_hats = {} if !$Trainer.dyed_hats
worn_hat = is_secondary ? @hat2 : @hat
$Trainer.dyed_hats[worn_hat] = value if value
refreshPlayerOutfit()
end
def hat_color=(value)
@hat_color = value
$Trainer.dyed_hats = {} if !$Trainer.dyed_hats
worn_hat = @hat
$Trainer.dyed_hats[worn_hat] = value if value
refreshPlayerOutfit()
end
def hat2_color=(value)
@hat2_color = value
$Trainer.dyed_hats = {} if !$Trainer.dyed_hats
worn_hat = @hat2
$Trainer.dyed_hats[worn_hat] = value if value
refreshPlayerOutfit()
end
def unlock_clothes(outfitID, silent = false)
update_global_clothes_list()
outfit = $PokemonGlobal.clothes_data[outfitID]
@unlocked_clothes = [] if !@unlocked_clothes
@unlocked_clothes << outfitID if !@unlocked_clothes.include?(outfitID)
if !silent
filename = getTrainerSpriteOutfitFilename(outfitID)
name = outfit ? outfit.name : outfitID
unlock_outfit_animation(filename, name)
end
end
def unlock_hat(hatID, silent = false)
update_global_hats_list()
hat = $PokemonGlobal.hats_data[hatID]
@unlocked_hats = [] if !@unlocked_hats
@unlocked_hats << hatID if !@unlocked_hats.include?(hatID)
if !silent
filename = getTrainerSpriteHatFilename(hatID)
name = hat ? hat.name : hatID
unlock_outfit_animation(filename, name)
end
end
def unlock_hair(hairID, silent = false)
update_global_hairstyles_list()
hairstyle = $PokemonGlobal.hairstyles_data[hairID]
if hairID.is_a?(Symbol)
hairID = HAIRSTYLES[hairID].id
end
@unlocked_hairstyles = [] if !@unlocked_hairstyles
@unlocked_hairstyles << hairID if !@unlocked_hairstyles.include?(hairID)
if !silent
filename = getTrainerSpriteHairFilename("2_" + hairID)
name = hairstyle ? hairstyle.name : hairID
unlock_outfit_animation(filename, name)
end
end
def unlock_outfit_animation(filepath, name, color = 2)
outfit_preview = PictureWindow.new(filepath)
outfit_preview.x = Graphics.width / 4
musicEffect = "Key item get"
pbMessage(_INTL("{1} obtained \\C[{2}]{3}\\C[0]!\\me[{4}]", $Trainer.name, color, name, musicEffect))
outfit_preview.dispose
end
def surfing_pokemon=(species)
@surfing_pokemon = species
end
def skin_tone=(value)
@skin_tone = value
$scene.reset_player_sprite
#$scene.spritesetGlobal.playersprite.updateCharacterBitmap
end
def beat_league=(value)
@beat_league = value
end
def new_game_plus_unlocked=(value)
@new_game_plus_unlocked = value
end
def seen?(species)
return @pokedex.seen?(species)
end
# (see Pokedex#owned?)
# Shorthand for +self.pokedex.owned?+.
def owned?(species)
return @pokedex.owned?(species)
end
def can_change_outfit()
return false if isOnPinkanIsland()
return true
end
alias playerAddOns_initialize initialize
def initialize(name, trainer_type)
playerAddOns_initialize(name,trainer_type)
@outfit = 0
@hat = 0
@hat2 = 0
@hair = 0
@clothes = 0
@hair_color = 0
@skin_tone = 0
@beat_league = false
@new_game_plus_unlocked = false
@new_game_plus = false
@surfing_pokemon = nil
@last_worn_outfit = nil
@last_worn_hat = nil
@last_worn_hat2 = nil
@dyed_hats = {}
@dyed_clothes = {}
@favorite_hat = nil
@favorite_hat2 =nil
@favorite_clothes = nil
@card_background = Settings::DEFAULT_TRAINER_CARD_BG
@unlocked_card_backgrounds = [@card_background]
@seen_qmarks_sprite = false
end
end

View File

@@ -0,0 +1,15 @@
class QuestReward
attr_accessor :item
attr_accessor :quantity
attr_accessor :nb_quests
attr_accessor :description
attr_accessor :can_have_multiple
def initialize(nb_quests,item,quantity,description,can_have_multiple=false)
@nb_quests =nb_quests
@item =item
@quantity =quantity
@description =description
@can_have_multiple = can_have_multiple
end
end

View File

@@ -0,0 +1,15 @@
# frozen_string_literal: true
#
# Rewards given by hotel questman after a certain nb. of completed quests
#
QUEST_REWARDS = [
QuestReward.new(1, :HM08, 1, "This HM will allow you to illuminate dark caves and should help you to progress in your journey!"),
QuestReward.new(5, :AMULETCOIN, 1, "This item will allows you to get twice the money in a battle if the Pokémon holding it took part in it!"),
QuestReward.new(10, :LANTERN, 1, "This will allow you to illuminate caves without having to use a HM! Practical, isn't it?"),
QuestReward.new(15, :LINKINGCORD, 3, "This strange cable triggers the evolution of Pokémon that typically evolve via trade. I know you'll put it to good use!"),
QuestReward.new(20, :SLEEPINGBAG, 1, "This handy item will allow you to sleep anywhere you want. You won't even need hotels anymore!"),
QuestReward.new(30, :MISTSTONE, 1, "This rare stone can evolve any Pokémon, regardless of their level or evolution method. Use it wisely!", true),
QuestReward.new(50, :GSBALL, 1, "This mysterious ball is rumored to be the key to call upon the protector of Ilex Forest. It's a precious relic."),
QuestReward.new(60, :MASTERBALL, 1, "This rare ball can catch any Pokémon. Don't waste it!", true),
]

View File

@@ -0,0 +1,111 @@
# frozen_string_literal: true
def setRivalStarter(starterIndex1, starterIndex2)
starter1 = obtainStarter(starterIndex1)
starter2 = obtainStarter(starterIndex2)
ensureRandomHashInitialized()
if $game_switches[SWITCH_RANDOM_WILD_TO_FUSION] # if fused starters, only take index 1
starter = obtainStarter(starterIndex1)
else
starter_body = starter1.id_number
starter_head = starter2.id_number
starter = getFusionSpecies(starter_body, starter_head).id_number
end
if $game_switches[SWITCH_RANDOM_STARTER_FIRST_STAGE]
starterSpecies = GameData::Species.get(starter)
starter = GameData::Species.get(starterSpecies.get_baby_species(false)).id_number
end
pbSet(VAR_RIVAL_STARTER, starter)
$game_switches[SWITCH_DEFINED_RIVAL_STARTER] = true
return starter
end
def ensureRandomHashInitialized()
if $PokemonGlobal.psuedoBSTHash == nil
psuedoHash = Hash.new
for i in 0..NB_POKEMON
psuedoHash[i] = i
end
$PokemonGlobal.psuedoBSTHash = psuedoHash
end
end
def displayRandomizerErrorMessage()
Kernel.pbMessage(_INTL("The randomizer has encountered an error. You should try to re-randomize your game as soon as possible."))
Kernel.pbMessage(_INTL("You can do this on the top floor of Pokémon Centers."))
end
def validate_regirock_steel_puzzle()
expected_pressed_switches = [75, 77, 74, 68, 73, 69]
expected_unpressed_switches = [76, 67, 72, 70]
switch_ids = [75, 77, 76, 67,
74, 68,
73, 72, 70, 69]
pressed_switches = []
unpressed_switches = []
switch_ids.each do |switch_id|
is_pressed = pbGetSelfSwitch(switch_id, "A")
if is_pressed
pressed_switches << switch_id
else
unpressed_switches << switch_id
end
end
for event_id in switch_ids
is_pressed = pbGetSelfSwitch(event_id, "A")
return false if !is_pressed && expected_pressed_switches.include?(event_id)
return false if is_pressed && expected_unpressed_switches.include?(event_id)
end
return true
end
def registeel_ice_press_switch(letter)
order = pbGet(VAR_REGI_PUZZLE_SWITCH_PRESSED)
solution = "ssBSBGG" # GGSBBss"
registeel_ice_reset_switches() if !order.is_a?(String)
order << letter
pbSet(VAR_REGI_PUZZLE_SWITCH_PRESSED, order)
if order == solution
echoln "OK"
pbSEPlay("Evolution start", nil, 130)
elsif order.length >= solution.length
registeel_ice_reset_switches()
end
echoln order
end
def registeel_ice_reset_switches()
switches_events = [66, 78, 84, 85, 86, 87, 88]
switches_events.each do |switch_id|
pbSetSelfSwitch(switch_id, "A", false)
echoln "reset" + switch_id.to_s
end
pbSet(VAR_REGI_PUZZLE_SWITCH_PRESSED, "")
end
def unpress_all_regirock_steel_switches()
switch_ids = [75, 77, 76, 67, 74, 68, 73, 72, 70, 69]
regi_map = 813
switch_ids.each do |event_id|
pbSetSelfSwitch(event_id, "A", false, regi_map)
end
end
# Solution: position of boulders [[x,y],[x,y],etc.]
def validate_regirock_ice_puzzle(solution)
for boulder_position in solution
x = boulder_position[0]
y = boulder_position[1]
# echoln ""
# echoln x.to_s + ", " + y.to_s
# echoln $game_map.event_at_position(x,y)
return false if !$game_map.event_at_position(x, y)
end
echoln "all boulders in place"
return true
end

View File

@@ -0,0 +1,88 @@
# Clefnair (Clefable) @ Life Orb
# Ability: Magic Guard
# Level: 33
# Fusion: Dragonair
# EVs: 252 HP / 252 SpD / 4 Spe
# Modest Nature
# - Dazzling Gleam
# - Dragon Breath
# - Wish
# - Water Pulse
def exportFusedPokemonForShowdown(pokemon)
if pokemon.species_data.is_a?(GameData::FusedSpecies)
head_pokemon_species = pokemon.species_data.head_pokemon
species_name = head_pokemon_species.name
else
species_name = pokemon.species_data.real_name
end
if pokemon.item
nameLine = _INTL("{1} ({2}) @ {3}", pokemon.name, species_name, pokemon.item.name)
else
nameLine = _INTL("{1} ({2})", pokemon.name, species_name)
end
abilityLine = _INTL("Ability: {1}", pokemon.ability.name)
levelLine = _INTL("Level: {1}", pokemon.level)
fusionLine = ""
if pokemon.species_data.is_a?(GameData::FusedSpecies)
body_pokemon_species = pokemon.species_data.body_pokemon
fusionLine = _INTL("Fusion: {1}\n", body_pokemon_species.name)
end
evsLine = calculateEvLineForShowdown(pokemon)
natureLine = "#{GameData::Nature.get(pokemon.nature).real_name} Nature"
ivsLine = calculateIvLineForShowdown(pokemon)
move1 = "", move2 = "", move3 = "", move4 = ""
move1 = _INTL("- {1}", GameData::Move.get(pokemon.moves[0].id).real_name) if pokemon.moves[0]
move2 = _INTL("- {1}", GameData::Move.get(pokemon.moves[1].id).real_name) if pokemon.moves[1]
move3 = _INTL("- {1}", GameData::Move.get(pokemon.moves[2].id).real_name) if pokemon.moves[2]
move4 = _INTL("- {1}", GameData::Move.get(pokemon.moves[3].id).real_name) if pokemon.moves[3]
ret = nameLine + "\n" +
abilityLine + "\n" +
levelLine + "\n" +
fusionLine +
evsLine + "\n" +
natureLine + "\n" +
ivsLine + "\n" +
move1 + "\n" +
move2 + "\n" +
move3 + "\n" +
move4 + "\n"
return ret
end
def calculateEvLineForShowdown(pokemon)
evsLine = "EVs: "
evsLine << _INTL("{1} HP /", pokemon.ev[:HP])
evsLine << _INTL("{1} Atk / ", pokemon.ev[:ATTACK])
evsLine << _INTL("{1} Def / ", pokemon.ev[:DEFENSE])
evsLine << _INTL("{1} SpA / ", pokemon.ev[:SPECIAL_ATTACK])
evsLine << _INTL("{1} SpD / ", pokemon.ev[:SPECIAL_DEFENSE])
evsLine << _INTL("{1} Spe / ", pokemon.ev[:SPEED])
return evsLine
end
def calculateIvLineForShowdown(pokemon)
ivLine = "IVs: "
ivLine << _INTL("{1} HP / ", pokemon.iv[:HP])
ivLine << _INTL("{1} Atk / ", pokemon.iv[:ATTACK])
ivLine << _INTL("{1} Def / ", pokemon.iv[:DEFENSE])
ivLine << _INTL("{1} SpA / ", pokemon.iv[:SPECIAL_ATTACK])
ivLine << _INTL("{1} SpD / ", pokemon.iv[:SPECIAL_DEFENSE])
ivLine << _INTL("{1} Spe", pokemon.iv[:SPEED])
return ivLine
end
def exportTeamForShowdown()
message = ""
for pokemon in $Trainer.party
message << exportFusedPokemonForShowdown(pokemon)
message << "\n"
end
Input.clipboard = message
end

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
[PICHU,2]
FormName = Spiky-Eared
Generation = 4
Evolution = PIKACHU,None
Evolutions = PIKACHU,None,
#-------------------------------
[UNOWN,1]
FormName = B

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -168,7 +168,7 @@ Generation = 6
[PICHU,2]
FormName = Spiky-Eared
Generation = 4
Evolution = PIKACHU,None
Evolutions = PIKACHU,None,
#-------------------------------
[AMPHAROS,1]
FormName = Mega Ampharos
@@ -276,7 +276,7 @@ Generation = 6
[SCIZOR,1]
FormName = Mega Scizor
MegaStone = SCIZORITE
BaseStats = 70,150,140,75,65,100
BaseStats = 70,150,140,65,100,75
Abilities = TECHNICIAN
HiddenAbilities = TECHNICIAN
Height = 2.0
@@ -1003,7 +1003,7 @@ BaseExp = 243
Moves = 1,TACKLE,1,VINEWHIP,6,FAIRYWIND,10,LUCKYCHANT,15,RAZORLEAF,20,WISH,25,MAGICALLEAF,27,GRASSYTERRAIN,33,PETALBLIZZARD,38,AROMATHERAPY,43,MISTYTERRAIN,46,MOONBLAST,50,LIGHTOFRUIN,51,PETALDANCE,58,SOLARBEAM
EggGroups = Undiscovered
Pokedex = The flower it's holding can no longer be found blooming anywhere. It's also thought to contain terrifying power.
Evolution = FLORGES,None
Evolutions = FLORGES,None,
#-------------------------------
[FLORGES,1]
FormName = Yellow Flower

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -82,9 +82,9 @@ Weight = 3.8
Color = Black
Pokedex = With its incisors, it gnaws through doors and infiltrates people's homes. Then, with a twitch of its whiskers, it steals whatever food it finds.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = PECHABERRY
Evolution = RATICATE,LevelNight,20
Evolutions = RATICATE,LevelNight,20
#-------------------------------
[RATICATE,1]
FormName = Alolan
@@ -97,7 +97,7 @@ Weight = 25.5
Color = Black
Pokedex = It forms a group of Rattata, which it assumes command of. Each group has its own territory, and disputes over food happen often.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = PECHABERRY
#-------------------------------
[RAICHU,1]
@@ -128,8 +128,8 @@ Weight = 40.0
Color = White
Pokedex = The skin on its back is as hard as steel. Predators go after its soft belly, so it clings to the ground desperately.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Evolution = SANDSLASH,Item,ICESTONE
Flags = InheritFormWithEverStone
Evolutions = SANDSLASH,Item,ICESTONE
#-------------------------------
[SANDSLASH,1]
FormName = Alolan
@@ -144,7 +144,7 @@ Weight = 55.0
Color = Blue
Pokedex = It runs across snow-covered plains at high speeds. It developed thick, sharp claws to plow through the snow.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[VULPIX,1]
FormName = Alolan
@@ -157,9 +157,9 @@ EggMoves = AGILITY,CHARM,DISABLE,ENCORE,EXTRASENSORY,FLAIL,FREEZEDRY,HOWL,HYPNOS
Color = White
Pokedex = In hot weather, this Pokémon makes ice shards with its six tails and sprays them around to cool itself off.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = SNOWBALL
Evolution = NINETALES,Item,ICESTONE
Evolutions = NINETALES,Item,ICESTONE
#-------------------------------
[NINETALES,1]
FormName = Alolan
@@ -173,7 +173,7 @@ TutorMoves = AQUATAIL,ATTRACT,AURORAVEIL,BLIZZARD,BODYSLAM,CALMMIND,CAPTIVATE,CO
Color = Blue
Pokedex = It lives on mountains perpetually covered in snow and is revered as a deity incarnate. It appears draped in a blizzard.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = SNOWBALL
#-------------------------------
[DIGLETT,1]
@@ -187,7 +187,7 @@ EggMoves = ANCIENTPOWER,BEATUP,ENDURE,FEINTATTACK,FINALGAMBIT,HEADBUTT,MEMENTO,M
Weight = 1.0
Pokedex = Its head sports an altered form of whiskers made of metal. When in communication with its comrades, its whiskers wobble to and fro.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[DUGTRIO,1]
FormName = Alolan
@@ -200,7 +200,7 @@ TutorMoves = AERIALACE,ATTRACT,BODYSLAM,BULLDOZE,CAPTIVATE,CONFIDE,CUT,DIG,DOUBL
Weight = 66.6
Pokedex = Its shining gold hair provides it with protection. It's reputed that keeping any of its fallen hairs will bring bad luck.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[MEOWTH,1]
FormName = Alolan
@@ -213,8 +213,8 @@ EggMoves = AMNESIA,ASSIST,CHARM,COVET,FLAIL,FLATTER,FOULPLAY,HYPNOSIS,PARTINGSHO
Color = Blue
Pokedex = It's impulsive, selfish, and fickle. It's very popular with some Trainers who like giving it the attention it needs.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Evolution = PERSIAN,Happiness
Flags = InheritFormWithEverStone
Evolutions = PERSIAN,Happiness,
#-------------------------------
[PERSIAN,1]
FormName = Alolan
@@ -229,7 +229,7 @@ Weight = 33.0
Color = Blue
Pokedex = Its round face is a symbol of wealth. Persian that have bigger, plumper faces are considered more beautiful.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[ALAKAZAM,1]
FormName = Mega Alakazam
@@ -254,7 +254,7 @@ Weight = 20.3
Color = Gray
Pokedex = Geodude compete against each other with headbutts. The iron sand on their heads will stick to whichever one has stronger magnetism.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = CELLBATTERY
#-------------------------------
[GRAVELER,1]
@@ -268,7 +268,7 @@ Weight = 110.0
Color = Gray
Pokedex = They eat rocks and often get into a scrap over them. The shock of Graveler smashing together causes a flash of light and a booming noise.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = CELLBATTERY
#-------------------------------
[GOLEM,1]
@@ -283,7 +283,7 @@ Weight = 316.0
Color = Gray
Pokedex = It fires rocks charged with electricity. Even if the rock isn't fired that accurately, just grazing an opponent will cause numbness and fainting.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemCommon = CELLBATTERY
#-------------------------------
[SLOWBRO,1]
@@ -312,7 +312,7 @@ Weight = 42.0
Color = Green
Pokedex = A Grimer, which had been brought in to solve a problem with garbage, developed over time into this form.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[MUK,1]
FormName = Alolan
@@ -326,7 +326,7 @@ Weight = 52.0
Color = Green
Pokedex = The garbage it eats causes continuous chemical changes in its body, which produce its exceedingly vivid coloration.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[GENGAR,1]
FormName = Mega Gengar
@@ -353,7 +353,7 @@ Generation = 7
#-------------------------------
[CUBONE,1]
Generation = 7
Evolution = MAROWAK,LevelNight,28
Evolutions = MAROWAK,LevelNight,28
#-------------------------------
[MAROWAK,1]
FormName = Alolan
@@ -444,7 +444,7 @@ Generation = 6
[PICHU,2]
FormName = Spiky-Eared
Generation = 4
Evolution = PIKACHU,None
Evolutions = PIKACHU,None,
#-------------------------------
[AMPHAROS,1]
FormName = Mega Ampharos
@@ -554,7 +554,7 @@ Generation = 6
[SCIZOR,1]
FormName = Mega Scizor
MegaStone = SCIZORITE
BaseStats = 70,150,140,75,65,100
BaseStats = 70,150,140,65,100,75
BaseExp = 210
Abilities = TECHNICIAN
HiddenAbilities = TECHNICIAN
@@ -1337,7 +1337,7 @@ BaseExp = 243
Moves = 1,TACKLE,1,VINEWHIP,1,FAIRYWIND,6,FAIRYWIND,10,LUCKYCHANT,15,RAZORLEAF,20,WISH,25,MAGICALLEAF,27,GRASSYTERRAIN,33,PETALBLIZZARD,38,AROMATHERAPY,43,MISTYTERRAIN,46,MOONBLAST,50,LIGHTOFRUIN,51,PETALDANCE,58,SOLARBEAM
EggGroups = Undiscovered
Pokedex = The flower it's holding can no longer be found blooming anywhere. It's also thought to contain terrifying power.
Evolution = FLORGES,None
Evolutions = FLORGES,None,
#-------------------------------
[FLORGES,1]
FormName = Yellow Flower
@@ -1515,7 +1515,7 @@ Pokedex = It summons the dead with its dreamy dancing. From their malice, it dra
Abilities = OWNTEMPO
HiddenAbilities = OWNTEMPO
Flags = InheritFormFromMother
Evolution = LYCANROC,LevelEvening,25
Evolutions = LYCANROC,LevelEvening,25
#-------------------------------
[LYCANROC,1]
FormName = Midnight Form

File diff suppressed because it is too large Load Diff

View File

@@ -479,7 +479,7 @@ Accuracy = 100
TotalPP = 5
Target = NearOther
FunctionCode = AlwaysCriticalHit
Flags = Contact,CanProtect,CanMirrorMove,Punching,CannotMetronome
Flags = Contact,CanProtect,CanMirrorMove,CannotMetronome
Description = Strikes with a fierce blow through mastery of the Dark style. Always results in a critical hit.
#-------------------------------
[LASHOUT]
@@ -519,19 +519,6 @@ FunctionCode = FailsIfTargetActed
Flags = Contact,CanProtect,CanMirrorMove
Description = This move enables the user to attack first. It fails if the target is not readying an attack, however.
#-------------------------------
[CEASELESSEDGE]
Name = Ceaseless Edge
Type = DARK
Category = Physical
Power = 65
Accuracy = 90
TotalPP = 15
Target = NearOther
FunctionCode = AddSpikesToFoeSide
Flags = Contact,CanProtect,CanMirrorMove,Slicing
EffectChance = 100
Description = The user slashes its shell blade at the target. This leaves shell splinters under the target as spikes.
#-------------------------------
[KNOCKOFF]
Name = Knock Off
Type = DARK
@@ -1221,19 +1208,6 @@ FunctionCode = NormalMovesBecomeElectric
Flags = Contact,CanProtect,CanMirrorMove,Punching,CannotMetronome
Description = The user attacks with electrically charged fists. Normal-type moves become Electric-type.
#-------------------------------
[WILDBOLTSTORM]
Name = Wildbolt Storm
Type = ELECTRIC
Category = Special
Power = 100
Accuracy = 80
TotalPP = 10
Target = AllNearFoes
FunctionCode = ParalyzeTargetAlwaysHitsInRain
Flags = CanProtect,CanMirrorMove,Wind
EffectChance = 20
Description = The user savagely attacks with lightning and wind. This may also leave the opponents with paralysis.
#-------------------------------
[THUNDERBOLT]
Name = Thunderbolt
Type = ELECTRIC
@@ -1592,19 +1566,6 @@ FunctionCode = UserFaintsPowersUpInMistyTerrainExplosive
Flags = CanProtect,CanMirrorMove
Description = The user attacks everything around and faints upon using this move. Power increases on Misty Terrain.
#-------------------------------
[SPRINGTIDESTORM]
Name = Springtide Storm
Type = FAIRY
Category = Special
Power = 100
Accuracy = 80
TotalPP = 5
Target = AllNearFoes
FunctionCode = LowerTargetAttack1
Flags = Wind,CanProtect,CanMirrorMove,CannotMetronome
EffectChance = 30
Description = The user attacks with fierce winds brimming with love and hate. This may also lower foes' Attack stats.
#-------------------------------
[MOONBLAST]
Name = Moonblast
Type = FAIRY
@@ -2005,19 +1966,6 @@ Flags = Contact,CanProtect,CanMirrorMove,CannotMetronome
EffectChance = 100
Description = Overwhelms the target with lightning-like movement, then kicks. Lowers the target's Defense stat.
#-------------------------------
[TRIPLEARROWS]
Name = Triple Arrows
Type = FIGHTING
Category = Physical
Power = 90
Accuracy = 100
TotalPP = 10
Target = NearOther
FunctionCode = LowerTargetDefense1FlinchTarget
Flags = CanProtect,CanMirrorMove,HighCriticalHitRate
EffectChance = 101
Description = This move is more likely to be a critical hit, and may also lower the target's Defense stat or make it flinch.
#-------------------------------
[SECRETSWORD]
Name = Secret Sword
Type = FIGHTING
@@ -2439,17 +2387,6 @@ Priority = 3
FunctionCode = ProtectUserSideFromPriorityMoves
Description = The user protects itself and its allies from priority moves. If may fail if used in succession.
#-------------------------------
[VICTORYDANCE]
Name = Victory Dance
Type = FIGHTING
Category = Status
Accuracy = 0
TotalPP = 10
Target = User
FunctionCode = RaiseUserAtkDefSpd1
Flags = Dance
Description = The user dances intensely to usher in victory, boosting its Attack, Defense and Speed stats.
#-------------------------------
[VCREATE]
Name = V-create
Type = FIRE
@@ -2574,18 +2511,6 @@ Flags = CanProtect,CanMirrorMove,ThawsUser,Bomb,CannotMetronome
EffectChance = 10
Description = Attacks by igniting a small stone and launching it as a fiery ball. May also burn the target.
#-------------------------------
[RAGINGFURY]
Name = Raging Fury
Type = FIRE
Category = Physical
Power = 120
Accuracy = 100
TotalPP = 10
Target = RandomNearFoe
FunctionCode = MultiTurnAttackConfuseUserAtEnd
Flags = CanProtect,CanMirrorMove,CannotMetronome
Description = The user rampages around spewing flames for two to three turns. The user then becomes confused.
#-------------------------------
[FIREBLAST]
Name = Fire Blast
Type = FIRE
@@ -2987,19 +2912,6 @@ FunctionCode = BurnAttackerBeforeUserActs
Flags = CanProtect,Bomb
Description = The user heats up its beak before attacking. Making contact in this time results in a burn.
#-------------------------------
[BLEAKWINDSTORM]
Name = Bleakwind Storm
Type = FLYING
Category = Special
Power = 100
Accuracy = 80
TotalPP = 10
Target = AllNearFoes
FunctionCode = LowerTargetSpeed1AlwaysHitsInRain
Flags = CanProtect,CanMirrorMove,Wind
EffectChance = 30
Description = The user attacks with savagely cold winds. This may also lower the Speed stats of opposing Pokémon.
#-------------------------------
[FLY]
Name = Fly
Type = FLYING
@@ -3346,19 +3258,6 @@ Flags = CanProtect,CanMirrorMove
EffectChance = 100
Description = The user attacks while also stitching the target's shadow to the ground to prevent it fleeing.
#-------------------------------
[BITTERMALICE]
Name = Bitter Malice
Type = GHOST
Category = Special
Power = 75
Accuracy = 100
TotalPP = 10
Target = NearOther
FunctionCode = LowerTargetAttack1
Flags = CanProtect,CanMirrorMove
EffectChance = 100
Description = The user attacks the target with spine-chilling resentment. This also lowers the target's Attack stat.
#-------------------------------
[SHADOWCLAW]
Name = Shadow Claw
Type = GHOST
@@ -3383,19 +3282,6 @@ FunctionCode = DoublePowerIfTargetStatusProblem
Flags = CanProtect,CanMirrorMove
Description = This relentless attack does massive damage to a target affected by status problems.
#-------------------------------
[INFERNALPARADE]
Name = Infernal Parade
Type = GHOST
Category = Special
Power = 60
Accuracy = 100
TotalPP = 15
Target = NearOther
FunctionCode = DoublePowerIfTargetStatusProblemBurnTarget
Flags = CanProtect,CanMirrorMove
EffectChance = 30
Description = The user attacks with fireballs that may cause a burn. Power doubles if the target has a status problem.
#-------------------------------
[OMINOUSWIND]
Name = Ominous Wind
Type = GHOST
@@ -3546,18 +3432,6 @@ FunctionCode = AddGhostTypeToTarget
Flags = CanProtect,CanMirrorMove
Description = The user takes the target trick-or-treating. This adds Ghost type to the target's type.
#-------------------------------
[CHLOROBLAST]
Name = Chloroblast
Type = GRASS
Category = Special
Power = 150
Accuracy = 95
TotalPP = 5
Target = NearOther
FunctionCode = RecoilHalfOfTotalHP
Flags = CanProtect,CanMirrorMove
Description = The user launches its amassed chlorophyll to inflict damage on the target. This also damages the user.
#-------------------------------
[FRENZYPLANT]
Name = Frenzy Plant
Type = GRASS
@@ -4121,18 +3995,6 @@ FunctionCode = SetTargetAbilityToInsomnia
Flags = CanProtect,CanMirrorMove
Description = A seed that causes worry is planted on the foe. It prevents sleep by making its Ability Insomnia.
#-------------------------------
[HEADLONGRUSH]
Name = Headlong Rush
Type = GROUND
Category = Physical
Power = 120
Accuracy = 100
TotalPP = 5
Target = NearOther
FunctionCode = LowerUserDefSpDef1
Flags = Contact,CanProtect,CanMirrorMove,Punching
Description = The user smashes into the target in a full-body tackle. This also lowers the user's Defense and Sp. Def.
#-------------------------------
[PRECIPICEBLADES]
Name = Precipice Blades
Type = GROUND
@@ -4157,19 +4019,6 @@ FunctionCode = DoublePowerIfTargetUnderground
Flags = CanProtect,CanMirrorMove
Description = The user sets off an earthquake that strikes every Pokémon around it.
#-------------------------------
[SANDSEARSTORM]
Name = Sandsear Storm
Type = GROUND
Category = Special
Power = 100
Accuracy = 80
TotalPP = 10
Target = AllNearFoes
FunctionCode = BurnTargetAlwaysHitsInRain
Flags = CanProtect,CanMirrorMove,Wind
EffectChance = 20
Description = The user wraps opposing Pokémon in searingly hot sand. This may also leave them with a burn.
#-------------------------------
[HIGHHORSEPOWER]
Name = High Horsepower
Type = GROUND
@@ -4519,19 +4368,6 @@ FunctionCode = LowerUserSpeed1
Flags = Contact,CanProtect,CanMirrorMove,Punching
Description = The user swings and hits with its strong, heavy fist. It lowers the user's Speed, however.
#-------------------------------
[MOUNTAINGALE]
Name = Mountain Gale
Type = ICE
Category = Physical
Power = 100
Accuracy = 85
TotalPP = 10
Target = NearOther
FunctionCode = FlinchTarget
Flags = CanProtect,CanMirrorMove
EffectChance = 30
Description = The user hurls giant chunks of ice at the target. This may also make the target flinch.
#-------------------------------
[ICEBEAM]
Name = Ice Beam
Type = ICE
@@ -6408,17 +6244,6 @@ FunctionCode = LowerTargetAttack1BypassSubstitute
Flags = CanMirrorMove
Description = The user and target become friends. The target loses its will to fight, lowering its Attack stat.
#-------------------------------
[POWERSHIFT]
Name = Power Shift
Type = NORMAL
Category = Status
Accuracy = 0
TotalPP = 10
Target = User
FunctionCode = UserSwapBaseAtkDef
Flags = CanMirrorMove,CannotMetronome
Description = The user swaps its Attack and Defense stats.
#-------------------------------
[PROTECT]
Name = Protect
Type = NORMAL
@@ -6895,19 +6720,6 @@ Flags = CanProtect,CanMirrorMove,Bomb
EffectChance = 30
Description = Unsanitary sludge is hurled at the target. It may also poison the target.
#-------------------------------
[DIRECLAW]
Name = Dire Claw
Type = POISON
Category = Physical
Power = 80
Accuracy = 100
TotalPP = 15
Target = NearOther
FunctionCode = PoisonParalyzeOrSleepTarget
Flags = Contact,CanProtect,CanMirrorMove
EffectChance = 50
Description = The user lashes out with ruinous claws. This may also leave the target poisoned, paralyzed or asleep.
#-------------------------------
[POISONJAB]
Name = Poison Jab
Type = POISON
@@ -6959,19 +6771,6 @@ FunctionCode = DoublePowerIfTargetPoisoned
Flags = CanProtect,CanMirrorMove
Description = The user drenches the foe in a special poisonous liquid. Its power doubles if the target is poisoned.
#-------------------------------
[BARBBARRAGE]
Name = Barb Barrage
Type = POISON
Category = Physical
Power = 60
Accuracy = 100
TotalPP = 10
Target = NearOther
FunctionCode = DoublePowerIfTargetPoisonedPoisonTarget
Flags = CanProtect,CanMirrorMove
EffectChance = 50
Description = The user fires toxic barbs that may poison the target. Power is doubled if the target is already poisoned.
#-------------------------------
[CLEARSMOG]
Name = Clear Smog
Type = POISON
@@ -7325,19 +7124,6 @@ Flags = CanProtect,CanMirrorMove,Sound
EffectChance = 100
Description = The user attacks with tremendous psychic power. This also removes 3 PP from the target's last move.
#-------------------------------
[ESPERWING]
Name = Esper Wing
Type = PSYCHIC
Category = Special
Power = 80
Accuracy = 100
TotalPP = 10
Target = NearOther
FunctionCode = RaiseUserSpeed1
Flags = CanProtect,CanMirrorMove,HighCriticalHitRate
EffectChance = 100
Description = The user slashes with aura-enriched wings, and boosts the user's Speed stat. High critical hit chance.
#-------------------------------
[EXPANDINGFORCE]
Name = Expanding Force
Type = PSYCHIC
@@ -7426,19 +7212,6 @@ Flags = CanProtect,CanMirrorMove,Bomb
EffectChance = 50
Description = A mistlike flurry of down envelops and damages the target. It may also lower the target's Sp. Atk.
#-------------------------------
[MYSTICALPOWER]
Name = Mystical Power
Type = PSYCHIC
Category = Special
Power = 70
Accuracy = 90
TotalPP = 10
Target = NearOther
FunctionCode = RaiseUserSpAtk1
Flags = CanProtect,CanMirrorMove
EffectChance = 100
Description = The user attacks by emitting a mysterious power. This also boosts the user's Sp. Atk stat.
#-------------------------------
[PSYCHOCUT]
Name = Psycho Cut
Type = PSYCHIC
@@ -7451,19 +7224,6 @@ FunctionCode = None
Flags = CanProtect,CanMirrorMove,HighCriticalHitRate
Description = The user tears at the target with blades formed by psychic power. Critical hits land more easily.
#-------------------------------
[PSYSHIELDBASH]
Name = Psyshield Bash
Type = PSYCHIC
Category = Physical
Power = 70
Accuracy = 90
TotalPP = 10
Target = NearOther
FunctionCode = RaiseUserDefense1
Flags = Contact,CanProtect,CanMirrorMove
EffectChance = 100
Description = The user slams into the target cloaked in psychic energy. This also boosts the user's Defense stat.
#-------------------------------
[PSYBEAM]
Name = Psybeam
Type = PSYCHIC
@@ -7729,16 +7489,6 @@ Target = UserSide
FunctionCode = StartWeakenSpecialDamageAgainstUserSide
Description = A wondrous wall of light is put up to suppress damage from special attacks for five turns.
#-------------------------------
[LUNARBLESSING]
Name = Lunar Blessing
Type = PSYCHIC
Category = Status
Accuracy = 0
TotalPP = 5
Target = UserAndAllies
FunctionCode = HealUserAndAlliesQuarterOfTotalHPCureStatus
Description = The user receives a blessing from the moon, healing HP and status problems for itself and its allies.
#-------------------------------
[LUNARDANCE]
Name = Lunar Dance
Type = PSYCHIC
@@ -7909,16 +7659,6 @@ FunctionCode = UserTargetSwapBaseSpeed
Flags = CanProtect,CanMirrorMove
Description = The user exchanges Speed stats with the target.
#-------------------------------
[TAKEHEART]
Name = Take Heart
Type = PSYCHIC
Category = Status
Accuracy = 0
TotalPP = 10
Target = User
FunctionCode = RaiseUserSpAtkSpDef1CureStatus
Description = The user lifts its spirits, curing its own status conditions and boosting its Sp. Atk and Sp. Def stats.
#-------------------------------
[TELEKINESIS]
Name = Telekinesis
Type = PSYCHIC
@@ -8062,19 +7802,6 @@ Flags = CanProtect,CanMirrorMove
EffectChance = 30
Description = Large boulders are hurled at the foes to inflict damage. It may also make the targets flinch.
#-------------------------------
[STONEAXE]
Name = Stone Axe
Type = ROCK
Category = Physical
Power = 65
Accuracy = 90
TotalPP = 15
Target = NearOther
FunctionCode = AddStealthRocksToFoeSide
Flags = Contact,CanProtect,CanMirrorMove,Slicing
EffectChance = 100
Description = The user swings its stone axes at the target. It leaves stone splinters around the target.
#-------------------------------
[ANCIENTPOWER]
Name = Ancient Power
Type = ROCK
@@ -8539,16 +8266,6 @@ FunctionCode = LowerTargetSpDef2
Flags = CanProtect,CanMirrorMove,Sound
Description = A horrible sound like scraping metal harshly reduces the target's Sp. Def stat.
#-------------------------------
[SHELTER]
Name = Shelter
Type = STEEL
Category = Status
Accuracy = 0
TotalPP = 10
Target = User
FunctionCode = RaiseUserDefense2
Description = The user makes its skin as hard as an iron shield, sharply boosting its Defense stat.
#-------------------------------
[SHIFTGEAR]
Name = Shift Gear
Type = STEEL
@@ -8583,18 +8300,6 @@ FunctionCode = PowerHigherWithUserHP
Flags = CanProtect,CanMirrorMove
Description = The user spouts water to damage the foe. The lower the user's HP, the less powerful it becomes.
#-------------------------------
[WAVECRASH]
Name = Wave Crash
Type = WATER
Category = Physical
Power = 120
Accuracy = 100
TotalPP = 10
Target = NearOther
FunctionCode = RecoilThirdOfDamageDealt
Flags = Contact,CanProtect,CanMirrorMove
Description = The user shrouds itself in water and slams with its whole body. This also hurts the user quite a lot.
#-------------------------------
[HYDROPUMP]
Name = Hydro Pump
Type = WATER
@@ -8703,7 +8408,7 @@ Accuracy = 100
TotalPP = 10
Target = NearOther
FunctionCode = DoublePowerIfTargetNotActed
Flags = Contact,CanProtect,CanMirrorMove,Biting
Flags = Contact,CanProtect,CanMirrorMove
Description = The user rends the target with its hard gills. Power doubles if the user moves first.
#-------------------------------
[LIQUIDATION]
@@ -8928,7 +8633,7 @@ Accuracy = 100
TotalPP = 5
Target = NearOther
FunctionCode = HitThreeTimesAlwaysCriticalHit
Flags = Contact,CanProtect,CanMirrorMove,Punching,CannotMetronome
Flags = Contact,CanProtect,CanMirrorMove,CannotMetronome
Description = Hits three times in a row with mastery of the Water style. This attack always deals critical hits.
#-------------------------------
[WATERSHURIKEN]

File diff suppressed because it is too large Load Diff

View File

@@ -82,9 +82,9 @@ Weight = 3.8
Color = Black
Pokedex = With its incisors, it gnaws through doors and infiltrates people's homes. Then, with a twitch of its whiskers, it steals whatever food it finds.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = PECHABERRY
Evolution = RATICATE,LevelNight,20
Evolutions = RATICATE,LevelNight,20
#-------------------------------
[RATICATE,1]
FormName = Alolan
@@ -97,7 +97,7 @@ Weight = 25.5
Color = Black
Pokedex = It forms a group of Rattata, which it assumes command of. Each group has its own territory, and disputes over food happen often.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = PECHABERRY
#-------------------------------
[RAICHU,1]
@@ -128,8 +128,8 @@ Weight = 40.0
Color = White
Pokedex = The skin on its back is as hard as steel. Predators go after its soft belly, so it clings to the ground desperately.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Evolution = SANDSLASH,Item,ICESTONE
Flags = InheritFormWithEverStone
Evolutions = SANDSLASH,Item,ICESTONE
#-------------------------------
[SANDSLASH,1]
FormName = Alolan
@@ -144,7 +144,7 @@ Weight = 55.0
Color = Blue
Pokedex = It runs across snow-covered plains at high speeds. It developed thick, sharp claws to plow through the snow.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[VULPIX,1]
FormName = Alolan
@@ -157,9 +157,9 @@ EggMoves = AGILITY,CHARM,DISABLE,ENCORE,EXTRASENSORY,FLAIL,FREEZEDRY,HOWL,HYPNOS
Color = White
Pokedex = In hot weather, this Pokémon makes ice shards with its six tails and sprays them around to cool itself off.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = SNOWBALL
Evolution = NINETALES,Item,ICESTONE
Evolutions = NINETALES,Item,ICESTONE
#-------------------------------
[NINETALES,1]
FormName = Alolan
@@ -173,7 +173,7 @@ TutorMoves = AGILITY,AQUATAIL,ATTRACT,AURORAVEIL,AVALANCHE,BLIZZARD,BODYSLAM,CAL
Color = Blue
Pokedex = It lives on mountains perpetually covered in snow and is revered as a deity incarnate. It appears draped in a blizzard.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = SNOWBALL
#-------------------------------
[DIGLETT,1]
@@ -187,7 +187,7 @@ EggMoves = ANCIENTPOWER,BEATUP,ENDURE,FEINTATTACK,FINALGAMBIT,HEADBUTT,MEMENTO,M
Weight = 1.0
Pokedex = Its head sports an altered form of whiskers made of metal. When in communication with its comrades, its whiskers wobble to and fro.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[DUGTRIO,1]
FormName = Alolan
@@ -200,7 +200,7 @@ TutorMoves = AERIALACE,AGILITY,ALLYSWITCH,ASSURANCE,ATTRACT,BEATUP,BODYSLAM,BULL
Weight = 66.6
Pokedex = Its shining gold hair provides it with protection. It's reputed that keeping any of its fallen hairs will bring bad luck.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[MEOWTH,1]
FormName = Alolan
@@ -213,8 +213,8 @@ EggMoves = AMNESIA,ASSIST,CHARM,COVET,FLAIL,FLATTER,FOULPLAY,HYPNOSIS,PARTINGSHO
Color = Blue
Pokedex = It's impulsive, selfish, and fickle. It's very popular with some Trainers who like giving it the attention it needs.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Evolution = PERSIAN,Happiness
Flags = InheritFormWithEverStone
Evolutions = PERSIAN,Happiness,
#-------------------------------
[MEOWTH,2]
FormName = Galarian
@@ -229,8 +229,8 @@ Color = Brown
Shape = BipedalTail
Pokedex = Living with a savage, seafaring people has toughened this Pokémon's body so much that parts of it have turned to iron.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
Evolution = PERRSERKER,Level,28
Flags = InheritFormWithEverStone
Evolutions = PERRSERKER,Level,28
#-------------------------------
[PERSIAN,1]
FormName = Alolan
@@ -245,34 +245,6 @@ Weight = 33.0
Color = Blue
Pokedex = Its round face is a symbol of wealth. Persian that have bigger, plumper faces are considered more beautiful.
Generation = 7
Flags = InheritFormWithEverstone
#-------------------------------
[GROWLITHE,1]
FormName = Hisuian
Types = FIRE,ROCK
BaseStats = 60,75,45,55,65,50
HiddenAbilities = ROCKHEAD
Moves = 1,EMBER,1,LEER,4,HOWL,8,BITE,12,FLAMEWHEEL,16,HELPINGHAND,24,FIREFANG,28,RETALIATE,32,CRUNCH,36,TAKEDOWN,40,FLAMETHROWER,44,ROAR,48,ROCKSLIDE,52,REVERSAL,56,FLAREBLITZ
TutorMoves = AGILITY,BODYSLAM,CLOSECOMBAT,CRUNCH,DIG,DOUBLEEDGE,ENDURE,FACADE,FIREBLAST,FIREFANG,FIRESPIN,FLAMECHARGE,FLAMETHROWER,FLAREBLITZ,HEATWAVE,HELPINGHAND,OUTRAGE,OVERHEAT,POWERGEM,PROTECT,PSYCHICFANGS,REST,REVERSAL,ROAR,ROCKBLAST,ROCKSLIDE,ROCKTOMB,SANDSTORM,SCARYFACE,SCORCHINGSANDS,SLEEPTALK,SMACKDOWN,SMARTSTRIKE,STEALTHROCK,STONEEDGE,SUBSTITUTE,SUNNYDAY,TAKEDOWN,THUNDERFANG,WILDCHARGE,WILLOWISP
EggMoves = COVET,DOUBLEEDGE,DOUBLEKICK,HEADSMASH,MORNINGSUN,THRASH
Height = 0.8
Weight = 22.7
Category = Scout
Pokedex = They patrol their territory in pairs. The igneous rock components in the fur of this species are the result of volcanic activity in its habitat.
Generation = 8
Flags = EggInRegion_3,InheritFormWithEverStone
#-------------------------------
[ARCANINE,1]
FormName = Hisuian
Types = FIRE,ROCK
BaseStats = 95,115,80,90,95,80
HiddenAbilities = ROCKHEAD
Moves = 0,EXTREMESPEED,1,FLAMEWHEEL,1,HELPINGHAND,1,AGILITY,1,FIREFANG,1,RETALIATE,1,CRUNCH,1,TAKEDOWN,1,ROAR,1,ROCKSLIDE,1,REVERSAL,1,FLAREBLITZ,1,ROCKTHROW,1,EMBER,1,LEER,1,HOWL,1,BITE,5,FLAMETHROWER,64,RAGINGFURY
TutorMoves = AERIALACE,AGILITY,BODYSLAM,BULLDOZE,CLOSECOMBAT,CRUNCH,DIG,DOUBLEEDGE,DRAGONPULSE,ENDURE,FACADE,FIREBLAST,FIREFANG,FIRESPIN,FLAMECHARGE,FLAMETHROWER,FLAREBLITZ,GIGAIMPACT,HEATCRASH,HEATWAVE,HELPINGHAND,HYPERBEAM,HYPERVOICE,IRONHEAD,OUTRAGE,OVERHEAT,POWERGEM,PROTECT,PSYCHICFANGS,REST,REVERSAL,ROAR,ROCKBLAST,ROCKSLIDE,ROCKTOMB,SANDSTORM,SCARYFACE,SCORCHINGSANDS,SLEEPTALK,SMACKDOWN,SMARTSTRIKE,SNARL,SOLARBEAM,STEALTHROCK,STONEEDGE,SUBSTITUTE,SUNNYDAY,TAKEDOWN,THIEF,THUNDERFANG,WILDCHARGE,WILLOWISP
Height = 2.0
Weight = 168.0
Pokedex = Snaps at its foes with fangs cloaked in blazing flame. Despite its bulk, it deftly feints every which way, leading opponents on a deceptively merry chase as it all but dances around them.
Generation = 8
Flags = InheritFormWithEverStone
#-------------------------------
[ALAKAZAM,1]
@@ -298,7 +270,7 @@ Weight = 20.3
Color = Gray
Pokedex = Geodude compete against each other with headbutts. The iron sand on their heads will stick to whichever one has stronger magnetism.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = CELLBATTERY
#-------------------------------
[GRAVELER,1]
@@ -312,7 +284,7 @@ Weight = 110.0
Color = Gray
Pokedex = They eat rocks and often get into a scrap over them. The shock of Graveler smashing together causes a flash of light and a booming noise.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemUncommon = CELLBATTERY
#-------------------------------
[GOLEM,1]
@@ -327,7 +299,7 @@ Weight = 316.0
Color = Gray
Pokedex = It fires rocks charged with electricity. Even if the rock isn't fired that accurately, just grazing an opponent will cause numbness and fainting.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemCommon = CELLBATTERY
#-------------------------------
[PONYTA,1]
@@ -343,7 +315,7 @@ Color = White
Category = Unique Horn
Pokedex = Its small horn hides a healing power. With a few rubs from this Pokémon's horn, any slight wound you have will be healed.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[RAPIDASH,1]
FormName = Galarian
@@ -357,7 +329,7 @@ Color = White
Category = Unique Horn
Pokedex = Little can stand up to its psycho cut. Unleashed from this Pokémon's horn, the move will punch a hole right through a thick metal sheet.
Generation = 8
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[SLOWPOKE,1]
FormName = Galarian
@@ -367,9 +339,8 @@ Moves = 1,TACKLE,1,CURSE,3,GROWL,6,ACID,9,YAWN,12,CONFUSION,15,DISABLE,18,WATERP
TutorMoves = AMNESIA,ATTRACT,BLIZZARD,BODYSLAM,BRINE,BULLDOZE,CALMMIND,CAPTIVATE,CONFIDE,DIG,DIVE,DOUBLEEDGE,DOUBLETEAM,EARTHQUAKE,ENDURE,EXPANDINGFORCE,FACADE,FIREBLAST,FLAMETHROWER,FOULPLAY,FRUSTRATION,FUTURESIGHT,GRASSKNOT,HAIL,HIDDENPOWER,HYDROPUMP,ICEBEAM,ICYWIND,IMPRISON,IRONTAIL,LIGHTSCREEN,LIQUIDATION,MIMIC,MUDSHOT,NATURALGIFT,PAYDAY,PROTECT,PSYCHIC,PSYCHICTERRAIN,PSYSHOCK,RAINDANCE,REST,RETURN,ROUND,SAFEGUARD,SCALD,SECRETPOWER,SHADOWBALL,SKILLSWAP,SLEEPTALK,SNORE,STOREDPOWER,SUBSTITUTE,SUNNYDAY,SURF,SWAGGER,SWIFT,THUNDERWAVE,TRIATTACK,TRICK,TRICKROOM,WEATHERBALL,WHIRLPOOL,WONDERROOM,ZENHEADBUTT
Pokedex = Although this Pokémon is normally zoned out, its expression abruptly sharpens on occasion. The cause for this seems to lie in Slowpoke's diet.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
Evolution = SLOWBRO,Item,GALARICACUFF
Evolution = SLOWKING,Item,GALARICAWREATH
Flags = InheritFormWithEverStone
Evolutions = SLOWBRO,Item,GALARICACUFF,SLOWKING,Item,GALARICAWREATH
#-------------------------------
[SLOWBRO,1]
FormName = Galarian
@@ -381,7 +352,7 @@ TutorMoves = AMNESIA,ATTRACT,AVALANCHE,BLIZZARD,BODYSLAM,BRICKBREAK,BRINE,BRUTAL
Weight = 70.5
Pokedex = If this Pokémon squeezes the tongue of the Shellder biting it, the Shellder will launch a toxic liquid from the tip of its shell.
Generation = 8
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[SLOWBRO,2]
FormName = Mega Slowbro
@@ -408,9 +379,9 @@ EggMoves = COUNTER,COVET,CURSE,DOUBLEEDGE,FEINT,FLAIL,NIGHTSLASH,QUICKATTACK,QUI
Weight = 42.0
Pokedex = The stalks of leeks are thicker and longer in the Galar region. Farfetch'd that adapted to these stalks took on a unique form.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
Flags = InheritFormWithEverStone
WildItemCommon = LEEK
Evolution = SIRFETCHD,AfterBattleCounter,3
Evolutions = SIRFETCHD,BattleDealCriticalHit,3
#-------------------------------
[GRIMER,1]
FormName = Alolan
@@ -425,7 +396,7 @@ Weight = 42.0
Color = Green
Pokedex = A Grimer, which had been brought in to solve a problem with garbage, developed over time into this form.
Generation = 7
Flags = EggInRegion_1,InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[MUK,1]
FormName = Alolan
@@ -439,7 +410,7 @@ Weight = 52.0
Color = Green
Pokedex = The garbage it eats causes continuous chemical changes in its body, which produce its exceedingly vivid coloration.
Generation = 7
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[GENGAR,1]
FormName = Mega Gengar
@@ -452,30 +423,6 @@ Height = 1.4
Pokedex = The energy of Mega Evolution awakened it. It sinks into another dimension, where it keeps a patient watch for its chance to attack.
Generation = 6
#-------------------------------
[VOLTORB,1]
FormName = Hisuian
Types = ELECTRIC,GRASS
Moves = 1,CHARGE,1,TACKLE,4,THUNDERSHOCK,6,STUNSPORE,9,BULLETSEED,11,ROLLOUT,13,SCREECH,16,CHARGEBEAM,20,SWIFT,22,ELECTROBALL,26,SELFDESTRUCT,29,ENERGYBALL,34,SEEDBOMB,34,DISCHARGE,41,EXPLOSION,46,GYROBALL,50,GRASSYTERRAIN
TutorMoves = AGILITY,BULLETSEED,CHARGE,CHARGEBEAM,DOUBLEEDGE,ELECTRICTERRAIN,ELECTROBALL,ELECTROWEB,ENDURE,ENERGYBALL,FACADE,FOULPLAY,GIGADRAIN,GRASSKNOT,GRASSYGLIDE,GRASSYTERRAIN,GYROBALL,LEAFSTORM,PROTECT,RAINDANCE,REFLECT,REST,SEEDBOMB,SLEEPTALK,SOLARBEAM,SUBSTITUTE,SWIFT,TAKEDOWN,TAUNT,THIEF,THUNDER,THUNDERBOLT,THUNDERWAVE,VOLTSWITCH,WILDCHARGE
EggMoves = LEECHSEED,RECYCLE,WORRYSEED
Weight = 13.0
Category = Sphere
Pokedex = An enigmatic Pokémon that happens to bear a resemblance to a Poké Ball. When excited, it discharges the electric current it has stored in its belly, then lets out a great, uproarious laugh.
Generation = 8
Flags = EggInRegion_3,InheritFormWithEverStone
Evolutions = ELECTRODE,Item,LEAFSTONE
#-------------------------------
[ELECTRODE,1]
FormName = Hisuian
Types = ELECTRIC,GRASS
Moves = 0,CHLOROBLAST,1,CHARGE,1,TACKLE,4,THUNDERSHOCK,6,STUNSPORE,9,BULLETSEED,11,ROLLOUT,13,SCREECH,16,CHARGEBEAM,20,SWIFT,22,ELECTROBALL,26,SELFDESTRUCT,29,ENERGYBALL,34,SEEDBOMB,34,DISCHARGE,41,EXPLOSION,46,GYROBALL,50,GRASSYTERRAIN
TutorMoves = AGILITY,BULLETSEED,CHARGE,CHARGEBEAM,CURSE,DOUBLEEDGE,ELECTRICTERRAIN,ELECTROBALL,ELECTROWEB,ENDURE,ENERGYBALL,FACADE,FOULPLAY,GIGADRAIN,GIGAIMPACT,GRASSKNOT,GRASSYGLIDE,GRASSYTERRAIN,GYROBALL,HYPERBEAM,LEAFSTORM,PROTECT,RAINDANCE,REFLECT,REST,SCARYFACE,SEEDBOMB,SLEEPTALK,SOLARBEAM,SUBSTITUTE,SWIFT,TAKEDOWN,TAUNT,THIEF,THUNDER,THUNDERBOLT,THUNDERWAVE,VOLTSWITCH,WILDCHARGE
Weight = 71.0
Category = Sphere
Pokedex = The tissue on the surface of its body is curiously similar in composition to an Apricorn. When irritated, this Pokémon lets loose an electric current equal to 20 lightning bolts.
Generation = 8
Flags = InheritFormWithEverStone
#-------------------------------
[EXEGGUTOR,1]
FormName = Alolan
Types = GRASS,DRAGON
@@ -490,14 +437,14 @@ Generation = 7
#-------------------------------
[CUBONE,1]
Generation = 7
Evolution = MAROWAK,LevelNight,28
Evolutions = MAROWAK,LevelNight,28
#-------------------------------
[MAROWAK,1]
FormName = Alolan
Types = FIRE,GHOST
Abilities = CURSEDBODY,LIGHTNINGROD
HiddenAbilities = ROCKHEAD
Moves = 1,SHADOWBONE,1,FALSESWIPE,1,HEADBUTT,1,RETALIATE,1,FOCUSENERGY,1,DOUBLEEDGE,1,MUDSLAP,1,GROWL,1,TAILWHIP,1,FIRESPIN,12,FLAMEWHEEL,16,HEX,20,FLING,24,STOMPINGTANTRUM,31,BONERUSH,36,WILLOWISP,42,ENDEAVOR,48,BONEMERANG,54,THRASH,60,FLAREBLITZ
Moves = 1,GROWL,1,TAILWHIP,1,BONECLUB,1,FLAMEWHEEL,3,TAILWHIP,7,BONECLUB,11,FLAMEWHEEL,13,LEER,17,HEX,21,BONEMERANG,23,WILLOWISP,27,SHADOWBONE,33,THRASH,37,FLING,43,STOMPINGTANTRUM,49,ENDEAVOR,53,FLAREBLITZ,59,RETALIATE,65,BONERUSH
TutorMoves = AERIALACE,ALLYSWITCH,ATTRACT,BLIZZARD,BODYSLAM,BRICKBREAK,BRUTALSWING,BULLDOZE,BURNINGJEALOUSY,CAPTIVATE,CONFIDE,COUNTER,DARKPULSE,DIG,DOUBLEEDGE,DOUBLETEAM,DREAMEATER,DYNAMICPUNCH,EARTHPOWER,EARTHQUAKE,ECHOEDVOICE,ENDEAVOR,ENDURE,FACADE,FALSESWIPE,FIREBLAST,FIREPUNCH,FIRESPIN,FLAMECHARGE,FLAMETHROWER,FLAREBLITZ,FLING,FOCUSBLAST,FOCUSENERGY,FOCUSPUNCH,FRUSTRATION,FURYCUTTER,GIGAIMPACT,HEADBUTT,HEATWAVE,HEX,HIDDENPOWER,HYPERBEAM,ICEBEAM,ICYWIND,IMPRISON,INCINERATE,IRONDEFENSE,IRONHEAD,IRONTAIL,KNOCKOFF,LASERFOCUS,LOWKICK,MEGAKICK,MEGAPUNCH,MIMIC,MUDSLAP,NATURALGIFT,OUTRAGE,PAINSPLIT,POLTERGEIST,POWERUPPUNCH,PROTECT,RAINDANCE,REST,RETALIATE,RETURN,ROCKCLIMB,ROCKSLIDE,ROCKSMASH,ROCKTOMB,ROUND,SANDSTORM,SCORCHINGSANDS,SCREECH,SECRETPOWER,SEISMICTOSS,SHADOWBALL,SLEEPTALK,SMACKDOWN,SNORE,SPITE,STEALTHROCK,STOMPINGTANTRUM,STONEEDGE,STRENGTH,SUBSTITUTE,SUNNYDAY,SWAGGER,SWIFT,SWORDSDANCE,THIEF,THROATCHOP,THUNDER,THUNDERBOLT,THUNDERPUNCH,UPROAR,WILLOWISP
Weight = 34.0
Color = Purple
@@ -543,8 +490,8 @@ Color = White
Category = Dancing
Pokedex = Its talent is tap-dancing. It can also manipulate temperatures to create a floor of ice, which this Pokémon can kick up to use as a barrier.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
Evolution = MRRIME,Level,42
Flags = InheritFormWithEverStone
Evolutions = MRRIME,Level,42
#-------------------------------
[PINSIR,1]
FormName = Mega Pinsir
@@ -653,23 +600,10 @@ Weight = 33.0
Pokedex = Despite its diminished size, its mental power has grown phenomenally. With a mere thought, it can smash a skyscraper to smithereens.
Generation = 6
#-------------------------------
[TYPHLOSION,1]
FormName = Hisuian
Types = FIRE,GHOST
BaseStats = 73,84,78,95,119,85
HiddenAbilities = FRISK
Moves = 0,INFERNALPARADE,1,ERUPTION,1,DOUBLEEDGE,1,GYROBALL,1,TACKLE,1,LEER,1,SMOKESCREEN,1,EMBER,13,QUICKATTACK,20,FLAMEWHEEL,24,DEFENSECURL,31,SWIFT,35,FLAMECHARGE,43,LAVAPLUME,48,FLAMETHROWER,56,INFERNO,61,ROLLOUT,74,OVERHEAT
TutorMoves = AERIALACE,BLASTBURN,BODYSLAM,BRICKBREAK,BULLDOZE,BURNINGJEALOUSY,CALMMIND,CONFUSERAY,CURSE,DIG,DOUBLEEDGE,EARTHQUAKE,ENDEAVOR,ENDURE,FACADE,FIREBLAST,FIREFANG,FIREPLEDGE,FIREPUNCH,FIRESPIN,FLAMECHARGE,FLAMETHROWER,FLAREBLITZ,FOCUSBLAST,FOCUSPUNCH,GIGAIMPACT,GYROBALL,HEATWAVE,HEX,HYPERBEAM,IRONHEAD,LOWKICK,NIGHTSHADE,OVERHEAT,PLAYROUGH,POLTERGEIST,PROTECT,REST,REVERSAL,ROAR,ROCKSLIDE,SHADOWBALL,SHADOWCLAW,SLEEPTALK,SOLARBEAM,SPITE,STOMPINGTANTRUM,SUBSTITUTE,SUNNYDAY,SWIFT,TAKEDOWN,THUNDERPUNCH,WILDCHARGE,WILLOWISP,ZENHEADBUTT
Height = 1.6
Weight = 69.8
Category = Ghost Flame
Pokedex = Said to purify lost, forsaken souls with its flames and guide them to the afterlife. I believe its form has been influenced by the energy of the sacred mountain towering at Hisui's center.
Generation = 8
#-------------------------------
[PICHU,2]
FormName = Spiky-Eared
Generation = 4
Evolution = PIKACHU,None
Evolutions = PIKACHU,None,
#-------------------------------
[AMPHAROS,1]
FormName = Mega Ampharos
@@ -693,7 +627,7 @@ Height = 1.8
Category = Hexpert
Pokedex = While chanting strange spells, this Pokémon combines its internal toxins with what it's eaten, creating strange potions.
Generation = 8
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[UNOWN,1]
FormName = B
@@ -789,22 +723,10 @@ Height = 10.5
Weight = 740.0
Generation = 6
#-------------------------------
[QWILFISH,1]
FormName = Hisuian
Types = DARK,POISON
Moves = 1,POISONSTING,1,TACKLE,4,HARDEN,8,BITE,12,FELLSTINGER,16,MINIMIZE,20,SPIKES,24,BRINE,28,BARBBARRAGE,32,PINMISSILE,36,TOXICSPIKES,40,STOCKPILE,40,SPITUP,44,TOXIC,48,CRUNCH,52,ACUPRESSURE,56,DESTINYBOND
TutorMoves = ACIDSPRAY,AGILITY,BLIZZARD,CRUNCH,CURSE,DARKPULSE,DOUBLEEDGE,ENDURE,FACADE,GIGAIMPACT,GUNKSHOT,GYROBALL,HAZE,HEX,HYDROPUMP,ICEBEAM,ICYWIND,LASHOUT,LIQUIDATION,MUDSHOT,PAINSPLIT,POISONJAB,POISONTAIL,PROTECT,RAINDANCE,REST,REVERSAL,SCALESHOT,SCARYFACE,SHADOWBALL,SLEEPTALK,SLUDGEBOMB,SPIKES,SPITE,SUBSTITUTE,SURF,SWIFT,SWORDSDANCE,TAKEDOWN,TAUNT,THROATCHOP,TOXIC,TOXICSPIKES,VENOSHOCK,WATERFALL,WATERPULSE
EggMoves = ACIDSPRAY,AQUAJET,AQUATAIL,ASTONISH,BUBBLEBEAM,FLAIL,HAZE,SELFDESTRUCT,SUPERSONIC,WATERPULSE
Color = Black
Pokedex = It absorbs toxins from the food it eats. The distinct purple spikes on its body are evidence of its potent poison.
Generation = 8
Flags = EggInRegion_3,InheritFormWithEverStone
Evolutions = OVERQWIL,HasMove,BARBBARRAGE
#-------------------------------
[SCIZOR,1]
FormName = Mega Scizor
MegaStone = SCIZORITE
BaseStats = 70,150,140,75,65,100
BaseStats = 70,150,140,65,100,75
BaseExp = 210
Abilities = TECHNICIAN
HiddenAbilities = TECHNICIAN
@@ -825,19 +747,6 @@ Weight = 62.5
Pokedex = A tremendous influx of energy builds it up, but when Mega Evolution ends, Heracross is bothered by terrible soreness in its muscles.
Generation = 6
#-------------------------------
[SNEASEL,1]
FormName = Hisuian
Types = FIGHTING,POISON
Moves = 1,SCRATCH,1,LEER,1,ROCKSMASH,6,TAUNT,12,QUICKATTACK,18,METALCLAW,24,POISONJAB,30,BRICKBREAK,36,HONECLAWS,42,SLASH,48,AGILITY,54,SCREECH,60,CLOSECOMBAT
TutorMoves = ACIDSPRAY,AERIALACE,AGILITY,BRICKBREAK,BULKUP,CALMMIND,CLOSECOMBAT,COACHING,DIG,ENDURE,FACADE,FALSESWIPE,FLING,FOCUSBLAST,FOCUSPUNCH,GIGAIMPACT,GRASSKNOT,GUNKSHOT,LASHOUT,LOWKICK,LOWSWEEP,METALCLAW,NASTYPLOT,POISONJAB,POISONTAIL,PROTECT,RAINDANCE,REST,REVERSAL,SHADOWBALL,SHADOWCLAW,SLEEPTALK,SLUDGEBOMB,SLUDGEWAVE,SPITE,SUBSTITUTE,SUNNYDAY,SWIFT,SWORDSDANCE,TAKEDOWN,TAUNT,THIEF,THROATCHOP,TOXIC,TOXICSPIKES,VACUUMWAVE,VENOSHOCK,XSCISSOR
EggMoves = COUNTER,DOUBLEHIT,FAKEOUT,FEINT,NIGHTSLASH,QUICKGUARD,SWITCHEROO
Weight = 27.0
Color = Gray
Pokedex = Its sturdy, curved claws are ideal for traversing precipitous cliffs. From the tips of these claws drips a venom that infiltrates the nerves of any prey caught in Sneasel's grasp.
Generation = 8
Flags = EggInRegion_3,InheritFormWithEverStone
Evolutions = SNEASLER,DayHoldItem,RAZORCLAW
#-------------------------------
[CORSOLA,1]
FormName = Galarian
Types = GHOST
@@ -851,8 +760,8 @@ Weight = 0.5
Color = White
Pokedex = Sudden climate change wiped out this ancient kind of Corsola. This Pokémon absorbs others' life-force through its branches.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
Evolution = CURSOLA,Level,38
Flags = InheritFormWithEverStone
Evolutions = CURSOLA,Level,38
#-------------------------------
[HOUNDOOM,1]
FormName = Mega Houndoom
@@ -917,7 +826,7 @@ EggMoves = KNOCKOFF,PARTINGSHOT,QUICKGUARD
Color = White
Pokedex = Its restlessness has it constantly running around. If it sees another Pokémon, it will purposely run into them in order to start a fight.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[LINOONE,1]
FormName = Galarian
@@ -926,8 +835,8 @@ Moves = 0,NIGHTSLASH,1,SWITCHEROO,1,PINMISSILE,1,BABYDOLLEYES,1,TACKLE,1,LEER,1,
TutorMoves = ASSURANCE,ATTRACT,BLIZZARD,BODYPRESS,BODYSLAM,CAPTIVATE,CONFIDE,DIG,DOUBLEEDGE,DOUBLETEAM,ENDURE,FACADE,FAKETEARS,FLING,FRUSTRATION,GIGAIMPACT,GRASSKNOT,GUNKSHOT,HELPINGHAND,HIDDENPOWER,HYPERBEAM,HYPERVOICE,ICEBEAM,ICYWIND,IRONTAIL,LASHOUT,MIMIC,MUDSHOT,NATURALGIFT,PAYBACK,PINMISSILE,PROTECT,RAINDANCE,REST,RETALIATE,RETURN,ROUND,SCARYFACE,SCREECH,SECRETPOWER,SEEDBOMB,SHADOWBALL,SHADOWCLAW,SLEEPTALK,SNARL,SNORE,STOMPINGTANTRUM,SUBSTITUTE,SUNNYDAY,SURF,SWAGGER,SWIFT,TAUNT,THIEF,THROATCHOP,THUNDER,THUNDERBOLT,THUNDERWAVE,TRICK,WHIRLPOOL,WORKUP
Pokedex = It uses its long tongue to taunt opponents. Once the opposition is enraged, this Pokémon hurls itself at the opponent, tackling them forcefully.
Generation = 8
Flags = InheritFormWithEverstone
Evolution = OBSTAGOON,LevelNight,35
Flags = InheritFormWithEverStone
Evolutions = OBSTAGOON,LevelNight,35
#-------------------------------
[GARDEVOIR,1]
FormName = Mega Gardevoir
@@ -1306,22 +1215,6 @@ BaseStats = 50,65,107,86,105,107
BaseExp = 182
Pokedex = This is Rotom after it's seized control of a lawn mower that has a special motor. As it mows down grass, it scatters the clippings everywhere.
#-------------------------------
[DIALGA,1]
FormName = Origin Forme
BaseStats = 100,100,120,90,150,120
Color = Blue
Height = 7.0
Weight = 850.0
Pokedex = Radiant light caused Dialga to take on a form bearing a striking resemblance to the creator Pokémon. Dialga now wields such colossal strength that one must conclude this is its true form.
#-------------------------------
[PALKIA,1]
FormName = Origin Forme
BaseStats = 90,100,100,120,150,120
Shape = Quadruped
Height = 6.3
Weight = 660.0
Pokedex = It soars across the sky in a form that greatly resembles the creator of all things. Perhaps this imitation of appearance is Palkia's strategy for gaining Arceus's powers.
#-------------------------------
[GIRATINA,1]
FormName = Origin Forme
BaseStats = 150,120,100,90,120,100
@@ -1416,17 +1309,6 @@ FormName = Fairy Type
Types = FAIRY
Generation = 6
#-------------------------------
[SAMUROTT,1]
FormName = Hisuian
Types = WATER,DARK
BaseStats = 90,108,80,85,100,65
EVs = ATTACK,3
Moves = 0,CEASELESSEDGE,1,SUCKERPUNCH,1,SLASH,1,MEGAHORN,1,TACKLE,1,TAILWHIP,1,WATERGUN,13,FOCUSENERGY,18,RAZORSHELL,21,FURYCUTTER,25,WATERPULSE,29,AERIALACE,34,AQUAJET,39,ENCORE,46,AQUATAIL,51,RETALIATE,58,SWORDSDANCE,63,HYDROPUMP
TutorMoves = AERIALACE,AIRSLASH,AVALANCHE,BLIZZARD,BODYSLAM,BRICKBREAK,BULLDOZE,DARKPULSE,DIG,DRILLRUN,ENCORE,ENDURE,FACADE,FALSESWIPE,FLING,FLIPTURN,GIGAIMPACT,GRASSKNOT,HELPINGHAND,HYDROCANNON,HYDROPUMP,HYPERBEAM,ICEBEAM,ICYWIND,KNOCKOFF,LASHOUT,LIQUIDATION,PROTECT,RAINDANCE,REST,SCARYFACE,SLEEPTALK,SMARTSTRIKE,SNARL,SUBSTITUTE,SURF,SWIFT,SWORDSDANCE,TAKEDOWN,TAUNT,THIEF,THROATCHOP,VACUUMWAVE,WATERFALL,WATERPLEDGE,WATERPULSE,WHIRLPOOL,XSCISSOR
Weight = 58.2
Pokedex = Hard of heart and deft of blade, this rare form of Samurott is a product of the Pokémon's evolution in the region of Hisui. Its turbulent blows crash into foes like ceaseless pounding waves.
Generation = 8
#-------------------------------
[AUDINO,1]
FormName = Mega Audino
MegaStone = AUDINITE
@@ -1440,51 +1322,12 @@ Weight = 32.0
Color = White
Generation = 6
#-------------------------------
[LILLIGANT,1]
FormName = Hisuian
Types = GRASS,FIGHTING
BaseStats = 70,105,75,105,50,75
EVs = ATTACK,1,SPEED,1
Abilities = CHLOROPHYLL,HUSTLE
Moves = 0,VICTORYDANCE,1,PETALBLIZZARD,1,TEETERDANCE,1,DEFOG,1,LEAFBLADE,1,MEGAKICK,1,SOLARBLADE,1,MEGADRAIN,1,MAGICALLEAF,1,SLEEPPOWDER,1,GIGADRAIN,1,LEECHSEED,1,AFTERYOU,1,ENERGYBALL,1,SYNTHESIS,1,SUNNYDAY,1,ENTRAINMENT,1,LEAFSTORM,1,ABSORB,1,GROWTH,1,HELPINGHAND,1,STUNSPORE,5,CLOSECOMBAT
TutorMoves = ACROBATICS,AERIALACE,AIRSLASH,BRICKBREAK,BULLETSEED,CHARM,CLOSECOMBAT,COACHING,ENCORE,ENDURE,ENERGYBALL,FACADE,GIGADRAIN,GIGAIMPACT,GRASSKNOT,GRASSYGLIDE,GRASSYTERRAIN,HELPINGHAND,HURRICANE,HYPERBEAM,LEAFSTORM,LOWKICK,LOWSWEEP,MAGICALLEAF,METRONOME,PETALBLIZZARD,POISONJAB,POLLENPUFF,PROTECT,PSYCHUP,RAINDANCE,REST,SEEDBOMB,SLEEPTALK,SOLARBEAM,SOLARBLADE,SUBSTITUTE,SUNNYDAY,SWORDSDANCE,TAKEDOWN,TRIPLEAXEL,VACUUMWAVE,WEATHERBALL
Shape = Bipedal
Height = 1.2
Weight = 19.2
Category = Spinning
Pokedex = I suspect that its well-developed legs are the result of a life spent on mountains covered in deep snow. The scent it exudes from its flower crown heartens those in proximity.
Generation = 8
#-------------------------------
[BASCULIN,1]
FormName = Blue-Striped
Abilities = ROCKHEAD,ADAPTABILITY
Pokedex = Even Basculin, which devours everything it can with its huge jaws, is nothing more than food to organisms stronger than itself.
WildItemUncommon = DEEPSEASCALE
#-------------------------------
[BASCULIN,2]
FormName = White-Striped
Abilities = RATTLED,ADAPTABILITY
Moves = 1,WATERGUN,1,TAILWHIP,4,TACKLE,8,FLAIL,12,AQUAJET,16,BITE,20,SCARYFACE,24,HEADBUTT,28,SOAK,32,CRUNCH,36,TAKEDOWN,40,UPROAR,44,WAVECRASH,48,THRASH,52,DOUBLEEDGE,56,HEADSMASH
TutorMoves = AGILITY,BLIZZARD,CRUNCH,DOUBLEEDGE,ENDEAVOR,ENDURE,FACADE,FLIPTURN,HYDROPUMP,ICEBEAM,ICEFANG,ICYWIND,LIQUIDATION,MUDDYWATER,MUDSHOT,PROTECT,PSYCHICFANGS,RAINDANCE,REST,SCALESHOT,SCARYFACE,SLEEPTALK,SUBSTITUTE,SURF,SWIFT,TAKEDOWN,UPROAR,WATERFALL,WATERPULSE,WHIRLPOOL,ZENHEADBUTT
EggMoves = ENDEAVOR
Category = Mellow
Pokedex = They live in frigid seas, forming schools and sharing food among themselves. When the time comes, they return to the river they were born in.
Generation = 8
Flags = InheritFormWithEverStone
Evolutions = BASCULEGION,Counter,294
#-------------------------------
[BASCULIN,3]
PokedexForm = 2
Abilities = RATTLED,ADAPTABILITY
Moves = 1,WATERGUN,1,TAILWHIP,4,TACKLE,8,FLAIL,12,AQUAJET,16,BITE,20,SCARYFACE,24,HEADBUTT,28,SOAK,32,CRUNCH,36,TAKEDOWN,40,UPROAR,44,WAVECRASH,48,THRASH,52,DOUBLEEDGE,56,HEADSMASH
TutorMoves = AGILITY,BLIZZARD,CRUNCH,DOUBLEEDGE,ENDEAVOR,ENDURE,FACADE,FLIPTURN,HYDROPUMP,ICEBEAM,ICEFANG,ICYWIND,LIQUIDATION,MUDDYWATER,MUDSHOT,PROTECT,PSYCHICFANGS,RAINDANCE,REST,SCALESHOT,SCARYFACE,SLEEPTALK,SUBSTITUTE,SURF,SWIFT,TAKEDOWN,UPROAR,WATERFALL,WATERPULSE,WHIRLPOOL,ZENHEADBUTT
EggMoves = ENDEAVOR
Category = Mellow
Pokedex = They live in frigid seas, forming schools and sharing food among themselves. When the time comes, they return to the river they were born in.
Generation = 8
Flags = InheritFormWithEverStone
Evolutions = BASCULEGION,Counter,294
#-------------------------------
[DARUMAKA,2]
FormName = Galarian
Types = ICE
@@ -1496,8 +1339,8 @@ Weight = 40.0
Color = White
Pokedex = The colder they get, the more energetic they are. They freeze their breath to make snowballs, using them as ammo for playful snowball fights.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
Evolution = DARMANITAN,Item,ICESTONE
Flags = InheritFormWithEverStone
Evolutions = DARMANITAN,Item,ICESTONE
#-------------------------------
[DARMANITAN,1]
FormName = Zen Mode
@@ -1520,7 +1363,7 @@ Color = White
Category = Zen Charm
Pokedex = On days when blizzards blow through, it comes down to where people live. It stashes food in the snowball on its head, taking it home for later.
Generation = 8
Flags = InheritFormWithEverstone
Flags = InheritFormWithEverStone
#-------------------------------
[DARMANITAN,3]
FormName = Galarian Zen Mode
@@ -1547,33 +1390,8 @@ Moves = 1,ASTONISH,1,PROTECT,4,HAZE,8,NIGHTSHADE,12,DISABLE,16,BRUTALSWING,20,CR
TutorMoves = ALLYSWITCH,ATTRACT,BRUTALSWING,CALMMIND,CAPTIVATE,CONFIDE,DARKPULSE,DOUBLEEDGE,DOUBLETEAM,EARTHPOWER,EARTHQUAKE,ENDURE,ENERGYBALL,FACADE,FAKETEARS,FRUSTRATION,HEX,HIDDENPOWER,IMPRISON,IRONDEFENSE,MIMIC,NASTYPLOT,NATURALGIFT,PAYBACK,POLTERGEIST,PROTECT,PSYCHIC,RAINDANCE,REST,RETURN,ROCKSLIDE,ROCKTOMB,ROUND,SAFEGUARD,SANDSTORM,SECRETPOWER,SHADOWBALL,SKILLSWAP,SLEEPTALK,SNORE,SUBSTITUTE,SWAGGER,THIEF,TOXIC,TOXICSPIKES,TRICK,TRICKROOM,WILLOWISP,WONDERROOM,ZENHEADBUTT
Pokedex = A clay slab with cursed engravings took possession of a Yamask. The slab is said to be absorbing the Yamask's dark power.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
Evolution = RUNERIGUS,AfterBattleCounterMakeReady,49
Evolution = RUNERIGUS,EventReady,2
#-------------------------------
[ZORUA,1]
FormName = Hisuian
Types = NORMAL,GHOST
BaseStats = 35,60,40,70,85,40
Moves = 1,SCRATCH,1,LEER,4,TORMENT,8,HONECLAWS,12,SHADOWSNEAK,16,CURSE,20,TAUNT,24,KNOCKOFF,28,SPITE,32,AGILITY,36,SHADOWBALL,40,BITTERMALICE,44,NASTYPLOT,48,FOULPLAY
TutorMoves = AGILITY,BURNINGJEALOUSY,CALMMIND,CONFUSERAY,CURSE,DARKPULSE,DIG,ENDURE,FACADE,FAKETEARS,FLING,FOCUSPUNCH,FOULPLAY,GIGAIMPACT,HEX,HYPERBEAM,ICYWIND,IMPRISON,KNOCKOFF,LASHOUT,NASTYPLOT,NIGHTSHADE,PAINSPLIT,PHANTOMFORCE,PROTECT,PSYCHUP,RAINDANCE,REST,ROAR,SHADOWBALL,SHADOWCLAW,SKITTERSMACK,SLEEPTALK,SLUDGEBOMB,SNARL,SPITE,SUBSTITUTE,SWIFT,TAKEDOWN,TAUNT,THIEF,TRICK,UTURN,WILLOWISP
EggMoves = DETECT,EXTRASENSORY,MEMENTO
Category = Spiteful Fox
Pokedex = A once-departed soul, returned to life in Hisui. Derives power from resentment, which rises as energy atop its head and takes on the forms of foes. In this way, Zorua vents lingering malice.
Generation = 8
Flags = EggInRegion_3,InheritFormWithEverStone
#-------------------------------
[ZOROARK,1]
FormName = Hisuian
Types = NORMAL,GHOST
BaseStats = 55,100,60,110,125,60
Moves = 0,SHADOWCLAW,1,UTURN,1,SCRATCH,1,LEER,1,TORMENT,1,HONECLAWS,12,SHADOWSNEAK,16,CURSE,20,TAUNT,24,KNOCKOFF,28,SPITE,34,AGILITY,40,SHADOWBALL,46,BITTERMALICE,52,NASTYPLOT,58,FOULPLAY
TutorMoves = AERIALACE,AGILITY,BODYSLAM,BRICKBREAK,BURNINGJEALOUSY,CALMMIND,CONFUSERAY,CRUNCH,CURSE,DARKPULSE,DIG,ENDURE,FACADE,FAKETEARS,FLAMETHROWER,FLING,FOCUSBLAST,FOCUSPUNCH,FOULPLAY,GIGAIMPACT,GRASSKNOT,HELPINGHAND,HEX,HYPERBEAM,HYPERVOICE,ICYWIND,IMPRISON,KNOCKOFF,LASHOUT,LOWKICK,LOWSWEEP,NASTYPLOT,NIGHTSHADE,PAINSPLIT,PHANTOMFORCE,POLTERGEIST,PROTECT,PSYCHIC,PSYCHUP,RAINDANCE,REST,ROAR,SCARYFACE,SHADOWBALL,SHADOWCLAW,SKITTERSMACK,SLEEPTALK,SLUDGEBOMB,SNARL,SPITE,SUBSTITUTE,SWIFT,SWORDSDANCE,TAKEDOWN,TAUNT,THIEF,THROATCHOP,TRICK,UTURN,WILLOWISP
Weight = 73.0
Category = Baneful Fox
Pokedex = With its disheveled white fur, it looks like an embodiment of death. Heedless of its own safety, Zoroark attacks its nemeses with a bitter energy so intense, it lacerates Zoroark's own body.
Generation = 8
Flags = InheritFormWithEverStone
Evolutions = RUNERIGUS,EventAfterDamageTaken,2
#-------------------------------
[DEERLING,1]
FormName = Summer Form
@@ -1609,22 +1427,7 @@ Weight = 20.5
Color = Green
Pokedex = Its conspicuous lips lure prey in as it lies in wait in the mud. When prey gets close, Stunfisk clamps its jagged steel fins down on them.
Generation = 8
Flags = EggInRegion_2,InheritFormWithEverstone
#-------------------------------
[BRAVIARY,1]
FormName = Hisuian
Types = PSYCHIC,FLYING
BaseStats = 110,83,70,65,112,70
EVs = SPECIAL_ATTACK,2
HiddenAbilities = TINTEDLENS
Moves = 0,ESPERWING,1,SUPERPOWER,1,SKYATTACK,1,PECK,1,LEER,1,HONECLAWS,1,WINGATTACK,18,TAILWIND,24,SCARYFACE,30,AERIALACE,36,SLASH,42,WHIRLWIND,48,CRUSHCLAW,57,AIRSLASH,64,DEFOG,72,THRASH,80,HURRICANE
TutorMoves = ACROBATICS,AERIALACE,AGILITY,AIRCUTTER,AIRSLASH,BODYSLAM,BRAVEBIRD,BULKUP,CALMMIND,CLOSECOMBAT,CONFUSERAY,DAZZLINGGLEAM,DOUBLEEDGE,DUALWINGBEAT,ENDURE,EXPANDINGFORCE,FACADE,FEATHERDANCE,FLY,FUTURESIGHT,GIGAIMPACT,HEATWAVE,HELPINGHAND,HURRICANE,HYPERBEAM,HYPERVOICE,ICYWIND,METALCLAW,NIGHTSHADE,PROTECT,PSYBEAM,PSYCHIC,PSYCHICTERRAIN,PSYCHUP,PSYSHOCK,RAINDANCE,REST,REVERSAL,ROCKSLIDE,ROCKTOMB,SCARYFACE,SHADOWBALL,SHADOWCLAW,SLEEPTALK,SNARL,STOREDPOWER,SUBSTITUTE,SUNNYDAY,SWIFT,TAILWIND,TAKEDOWN,UTURN,VACUUMWAVE,ZENHEADBUTT
Height = 1.7
Weight = 43.4
Color = White
Category = Battle Cry
Pokedex = Screaming a bloodcurdling battle cry, this huge and ferocious bird Pokémon goes out on the hunt. It blasts lakes with shock waves, then scoops up any prey that float to the water's surface.
Generation = 8
Flags = InheritFormWithEverStone
#-------------------------------
[TORNADUS,1]
FormName = Therian Forme
@@ -1659,7 +1462,7 @@ BaseStats = 125,120,90,95,170,100
BaseExp = 350
EVs = SPECIAL_ATTACK,3
Abilities = TURBOBLAZE
Moves = 1,DRAGONBREATH,1,NOBLEROAR,1,ANCIENTPOWER,1,FREEZEDRY,8,SLASH,16,ENDEAVOR,24,DRAGONPULSE,32,ICEBEAM,40,HYPERVOICE,48,FUSIONFLARE,56,BLIZZARD,64,IMPRISON,72,OUTRAGE,80,ICEBURN,88,SHEERCOLD
Moves = 1,ICYWIND,1,DRAGONRAGE,8,IMPRISON,15,ANCIENTPOWER,22,ICEBEAM,29,DRAGONBREATH,36,SLASH,43,FUSIONFLARE,50,ICEBURN,57,DRAGONPULSE,64,NOBLEROAR,71,ENDEAVOR,78,BLIZZARD,85,OUTRAGE,92,HYPERVOICE
Height = 3.6
Pokedex = It has foreseen that a world of truth will arrive for people and Pokémon. It strives to protect that future.
#-------------------------------
@@ -1669,7 +1472,7 @@ BaseStats = 125,170,100,95,120,90
BaseExp = 350
EVs = ATTACK,3
Abilities = TERAVOLT
Moves = 1,DRAGONBREATH,1,NOBLEROAR,1,ANCIENTPOWER,1,FREEZEDRY,8,SLASH,16,ENDEAVOR,24,DRAGONPULSE,32,ICEBEAM,40,HYPERVOICE,48,FUSIONBOLT,56,BLIZZARD,64,IMPRISON,72,OUTRAGE,80,FREEZESHOCK,88,SHEERCOLD
Moves = 1,ICYWIND,1,DRAGONRAGE,8,IMPRISON,15,ANCIENTPOWER,22,ICEBEAM,29,DRAGONBREATH,36,SLASH,43,FUSIONBOLT,50,FREEZESHOCK,57,DRAGONPULSE,64,NOBLEROAR,71,ENDEAVOR,78,BLIZZARD,85,OUTRAGE,92,HYPERVOICE
Height = 3.3
Pokedex = It's said that this Pokémon battles in order to protect the ideal world that will exist in the future for people and Pokémon.
#-------------------------------
@@ -1814,7 +1617,7 @@ BaseExp = 243
Moves = 1,TACKLE,1,VINEWHIP,1,FAIRYWIND,6,FAIRYWIND,10,LUCKYCHANT,15,RAZORLEAF,20,WISH,25,MAGICALLEAF,27,GRASSYTERRAIN,33,PETALBLIZZARD,38,AROMATHERAPY,43,MISTYTERRAIN,46,MOONBLAST,50,LIGHTOFRUIN,51,PETALDANCE,58,SOLARBEAM
EggGroups = Undiscovered
Pokedex = The flower it's holding can no longer be found blooming anywhere. It's also thought to contain terrifying power.
Evolution = FLORGES,None
Evolutions = FLORGES,None,
#-------------------------------
[FLORGES,1]
FormName = Yellow Flower
@@ -1858,8 +1661,7 @@ FormName = Pharaoh Trim
[MEOWSTIC,1]
FormName = Female
HiddenAbilities = COMPETITIVE
Moves = 1,MAGICALLEAF,1,SCRATCH,1,LEER,1,FAKEOUT,1,DISARMINGVOICE,9,CONFUSION,12,STOREDPOWER,15,CHARGEBEAM,18,COVET,21,PSYBEAM,24,SUCKERPUNCH,29,ROLEPLAY,34,LIGHTSCREEN,34,REFLECT,39,PSYSHOCK,44,EXTRASENSORY,49,SHADOWBALL,54,PSYCHIC,59,FUTURESIGHT
TutorMoves = ALLYSWITCH,ATTRACT,CALMMIND,CAPTIVATE,CHARGEBEAM,CHARM,CONFIDE,COVET,CUT,DARKPULSE,DIG,DOUBLETEAM,DREAMEATER,ECHOEDVOICE,ENDURE,ENERGYBALL,EXPANDINGFORCE,FACADE,FAKETEARS,FLASH,FRUSTRATION,FUTURESIGHT,GIGAIMPACT,GRAVITY,HEALBELL,HELPINGHAND,HIDDENPOWER,HYPERBEAM,IRONTAIL,LIGHTSCREEN,MAGICALLEAF,MAGICCOAT,MAGICROOM,MIMIC,NASTYPLOT,NATURALGIFT,PAYBACK,PAYDAY,PLAYROUGH,POWERUPPUNCH,PROTECT,PSYCHIC,PSYCHICTERRAIN,PSYCHUP,PSYSHOCK,RAINDANCE,RECYCLE,REFLECT,REST,RETURN,ROLEPLAY,ROUND,SAFEGUARD,SECRETPOWER,SHADOWBALL,SHOCKWAVE,SIGNALBEAM,SKILLSWAP,SLEEPTALK,SNATCH,SNORE,STOREDPOWER,SUBSTITUTE,SUNNYDAY,SWAGGER,SWIFT,TAILSLAP,TELEKINESIS,THUNDERBOLT,THUNDERWAVE,TORMENT,TOXIC,TRICK,TRICKROOM,WONDERROOM,WORKUP,ZENHEADBUTT
Moves = 1,STOREDPOWER,1,MEFIRST,1,MAGICALLEAF,1,SCRATCH,1,LEER,1,COVET,1,CONFUSION,5,COVET,9,CONFUSION,13,LIGHTSCREEN,17,PSYBEAM,19,FAKEOUT,22,DISARMINGVOICE,25,PSYSHOCK,28,CHARGEBEAM,31,SHADOWBALL,35,EXTRASENSORY,40,PSYCHIC,43,ROLEPLAY,45,SIGNALBEAM,48,SUCKERPUNCH,50,FUTURESIGHT,53,STOREDPOWER
Color = White
Pokedex = Females are a bit more selfish and aggressive than males. If they don't get what they want, they will torment you with their psychic abilities.
#-------------------------------
@@ -1869,32 +1671,6 @@ BaseStats = 60,140,50,60,140,50
EVs = ATTACK,2,SPECIAL_ATTACK,1
Pokedex = Once upon a time, a king with an Aegislash reigned over the land. His Pokémon eventually drained him of life, and his kingdom fell with him.
#-------------------------------
[SLIGGOO,1]
FormName = Hisuian
Types = STEEL,DRAGON
BaseStats = 58,75,83,40,83,113
Abilities = SAPSIPPER,SHELLARMOR
Moves = 0,SHELTER,1,ACIDARMOR,1,ABSORB,1,TACKLE,1,WATERGUN,1,DRAGONBREATH,15,PROTECT,20,FLAIL,25,WATERPULSE,30,RAINDANCE,35,DRAGONPULSE,43,CURSE,49,IRONHEAD,56,MUDDYWATER
TutorMoves = ACIDSPRAY,BLIZZARD,BODYSLAM,CHARM,CURSE,DRACOMETEOR,DRAGONPULSE,ENDURE,FACADE,FLASHCANNON,GYROBALL,HEAVYSLAM,ICEBEAM,IRONHEAD,MUDDYWATER,MUDSHOT,OUTRAGE,PROTECT,RAINDANCE,REST,ROCKSLIDE,ROCKTOMB,SANDSTORM,SKITTERSMACK,SLEEPTALK,SLUDGEBOMB,SLUDGEWAVE,STEELBEAM,SUBSTITUTE,SUNNYDAY,TAKEDOWN,THUNDER,THUNDERBOLT,WATERPULSE
Height = 0.7
Weight = 68.5
Category = Snail
Pokedex = A creature given to melancholy. I suspect its metallic shell developed as a result of the mucus on its skin reacting with the iron in Hisui's water.
Generation = 8
#-------------------------------
[GOODRA,1]
FormName = Hisuian
Types = STEEL,DRAGON
BaseStats = 80,100,100,60,110,150
Abilities = SAPSIPPER,SHELLARMOR
Moves = 0,IRONTAIL,1,SHELTER,1,ACIDSPRAY,1,TEARFULLOOK,1,FEINT,1,ABSORB,1,TACKLE,1,WATERGUN,1,DRAGONBREATH,15,PROTECT,20,FLAIL,25,WATERPULSE,30,RAINDANCE,35,DRAGONPULSE,43,CURSE,49,IRONHEAD,49,BODYSLAM,58,MUDDYWATER,67,HEAVYSLAM
TutorMoves = ACIDSPRAY,BLIZZARD,BODYPRESS,BODYSLAM,BREAKINGSWIPE,BULLDOZE,CHARM,CURSE,DRACOMETEOR,DRAGONCLAW,DRAGONPULSE,DRAGONTAIL,EARTHQUAKE,ENDURE,FACADE,FIREBLAST,FIREPUNCH,FLAMETHROWER,FLASHCANNON,GIGAIMPACT,GYROBALL,HEAVYSLAM,HYDROPUMP,HYPERBEAM,ICEBEAM,IRONHEAD,KNOCKOFF,LASHOUT,MUDDYWATER,MUDSHOT,OUTRAGE,PROTECT,RAINDANCE,REST,ROCKSLIDE,ROCKTOMB,SANDSTORM,SCARYFACE,SKITTERSMACK,SLEEPTALK,SLUDGEBOMB,SLUDGEWAVE,STEELBEAM,STOMPINGTANTRUM,SUBSTITUTE,SUNNYDAY,SURF,TAKEDOWN,THUNDER,THUNDERBOLT,THUNDERPUNCH,WATERPULSE,WEATHERBALL
Height = 1.7
Weight = 334.1
Category = Shell Bunker
Pokedex = Able to freely control the hardness of its metallic shell. It loathes solitude and is extremely clingy—it will fume and run riot if those dearest to it ever leave its side.
Generation = 8
#-------------------------------
[PUMPKABOO,1]
FormName = Average Size
BaseStats = 49,66,70,51,44,55
@@ -1947,18 +1723,6 @@ WildItemCommon = MIRACLESEED
WildItemUncommon = MIRACLESEED
WildItemRare = MIRACLESEED
#-------------------------------
[AVALUGG,1]
FormName = Hisuian
Types = ICE,ROCK
BaseStats = 95,127,184,38,34,36
Abilities = STRONGJAW,ICEBODY
Moves = 0,ROCKSLIDE,1,WIDEGUARD,1,RAPIDSPIN,1,HARDEN,1,TACKLE,1,POWDERSNOW,9,CURSE,12,ICYWIND,15,PROTECT,18,AVALANCHE,21,BITE,24,ICEFANG,27,IRONDEFENSE,30,RECOVER,33,CRUNCH,36,TAKEDOWN,41,BLIZZARD,46,DOUBLEEDGE,51,STONEEDGE,61,MOUNTAINGALE
TutorMoves = AVALANCHE,BLIZZARD,BODYPRESS,BODYSLAM,BULLDOZE,CRUNCH,CURSE,DIG,DOUBLEEDGE,EARTHQUAKE,ENDURE,FACADE,GIGAIMPACT,GYROBALL,HEAVYSLAM,HIGHHORSEPOWER,HYPERBEAM,ICEBEAM,ICEFANG,ICICLESPEAR,ICYWIND,IRONDEFENSE,IRONHEAD,METEORBEAM,PROTECT,RAINDANCE,REST,ROCKBLAST,ROCKSLIDE,ROCKTOMB,SANDSTORM,SCARYFACE,SLEEPTALK,STEALTHROCK,STOMPINGTANTRUM,STONEEDGE,SUBSTITUTE,TAKEDOWN
Height = 1.4
Weight = 262.4
Pokedex = The armor of ice covering its lower jaw puts steel to shame and can shatter rocks with ease. This Pokémon barrels along steep mountain paths, cleaving through the deep snow.
Generation = 8
#-------------------------------
[XERNEAS,1]
FormName = Active Mode
#-------------------------------
@@ -2017,17 +1781,6 @@ Height = 6.5
Weight = 490.0
Shape = BipedalTail
#-------------------------------
[DECIDUEYE,1]
FormName = Hisuian
Types = GRASS,FIGHTING
BaseStats = 88,112,80,60,95,95
HiddenAbilities = SCRAPPY
Moves = 0,TRIPLEARROWS,1,LEAFSTORM,1,UTURN,1,TACKLE,1,GROWL,1,LEAFAGE,9,PECK,12,SHADOWSNEAK,15,RAZORLEAF,20,SYNTHESIS,25,PLUCK,30,BULKUP,37,SUCKERPUNCH,44,LEAFBLADE,51,FEATHERDANCE,58,BRAVEBIRD
TutorMoves = AERIALACE,AIRCUTTER,AIRSLASH,AURASPHERE,BATONPASS,BRAVEBIRD,BRICKBREAK,BULKUP,BULLETSEED,CLOSECOMBAT,COACHING,CONFUSERAY,DUALWINGBEAT,ENDURE,ENERGYBALL,FACADE,FALSESWIPE,FEATHERDANCE,FOCUSBLAST,FOCUSPUNCH,FRENZYPLANT,GIGADRAIN,GIGAIMPACT,GRASSKNOT,GRASSPLEDGE,GRASSYGLIDE,GRASSYTERRAIN,HAZE,HELPINGHAND,HYPERBEAM,KNOCKOFF,LEAFSTORM,LIGHTSCREEN,LOWKICK,LOWSWEEP,MAGICALLEAF,NASTYPLOT,NIGHTSHADE,PROTECT,RAINDANCE,REST,REVERSAL,ROCKTOMB,SCARYFACE,SEEDBOMB,SHADOWCLAW,SLEEPTALK,SMACKDOWN,SOLARBEAM,SUBSTITUTE,SUNNYDAY,SWIFT,SWORDSDANCE,TAILWIND,TAKEDOWN,TAUNT,UTURN
Weight = 37.0
Pokedex = The air stored inside the rachises of Decidueye's feathers insulates the Pokémon against Hisui's extreme cold. This is firm proof that evolution can be influenced by environment.
Generation = 8
#-------------------------------
[ORICORIO,1]
FormName = Pom-Pom Style
Types = ELECTRIC,FLYING
@@ -2050,15 +1803,15 @@ Pokedex = It summons the dead with its dreamy dancing. From their malice, it dra
Abilities = OWNTEMPO
HiddenAbilities = OWNTEMPO
Flags = InheritFormFromMother
Evolution = LYCANROC,LevelEvening,25
Evolutions = LYCANROC,LevelEvening,25
#-------------------------------
[LYCANROC,1]
FormName = Midnight Form
BaseStats = 85,115,75,82,55,75
Abilities = KEENEYE,VITALSPIRIT
HiddenAbilities = NOGUARD
Moves = 0,COUNTER,1,ENDURE,1,REVERSAL,1,TAUNT,1,TACKLE,1,LEER,1,SANDATTACK,1,DOUBLETEAM,12,ROCKTHROW,16,HOWL,20,BITE,24,ROCKTOMB,30,ROAR,36,ROCKSLIDE,42,CRUNCH,48,SCARYFACE,54,STEALTHROCK,60,STONEEDGE
TutorMoves = ATTRACT,BRICKBREAK,BULKUP,CAPTIVATE,CLOSECOMBAT,CONFIDE,COVET,CRUNCH,DOUBLETEAM,EARTHPOWER,ECHOEDVOICE,ENDEAVOR,ENDURE,FACADE,FIREFANG,FIREPUNCH,FOULPLAY,FRUSTRATION,GIGAIMPACT,HIDDENPOWER,HYPERVOICE,IRONDEFENSE,IRONHEAD,IRONTAIL,LASHOUT,LASTRESORT,LOWSWEEP,MEGAKICK,MEGAPUNCH,MIMIC,NATURALGIFT,OUTRAGE,PAYBACK,PLAYROUGH,PROTECT,PSYCHICFANGS,REST,RETURN,REVENGE,REVERSAL,ROAR,ROCKBLAST,ROCKPOLISH,ROCKSLIDE,ROCKTOMB,ROUND,SANDSTORM,SCARYFACE,SECRETPOWER,SLEEPTALK,SNARL,SNORE,STEALTHROCK,STOMPINGTANTRUM,STONEEDGE,SUBSTITUTE,SWAGGER,SWORDSDANCE,TAUNT,THROATCHOP,THUNDERFANG,THUNDERPUNCH,TOXIC,UPROAR,ZENHEADBUTT
Moves = 0,COUNTER,1,REVERSAL,1,TAUNT,1,TACKLE,1,LEER,1,SANDATTACK,1,BITE,4,SANDATTACK,7,BITE,12,HOWL,15,ROCKTHROW,18,ODORSLEUTH,23,ROCKTOMB,26,ROAR,29,STEALTHROCK,34,ROCKSLIDE,37,SCARYFACE,40,CRUNCH,45,ROCKCLIMB,48,STONEEDGE
TutorMoves = ATTRACT,BRICKBREAK,BULKUP,CAPTIVATE,CLOSECOMBAT,CONFIDE,COVET,CRUNCH,DOUBLEEDGE,DOUBLETEAM,DUALCHOP,EARTHPOWER,ECHOEDVOICE,ENDEAVOR,ENDURE,FACADE,FIREFANG,FIREPUNCH,FOCUSPUNCH,FOULPLAY,FRUSTRATION,GIGAIMPACT,HIDDENPOWER,HYPERVOICE,IRONDEFENSE,IRONHEAD,IRONTAIL,LASERFOCUS,LASHOUT,LASTRESORT,LOWSWEEP,MEGAKICK,MEGAPUNCH,MIMIC,NATURALGIFT,OUTRAGE,PAYBACK,PLAYROUGH,PROTECT,PSYCHICFANGS,REST,RETURN,REVENGE,REVERSAL,ROAR,ROCKBLAST,ROCKPOLISH,ROCKSLIDE,ROCKTOMB,ROUND,SANDSTORM,SCARYFACE,SECRETPOWER,SLEEPTALK,SNARL,SNORE,STEALTHROCK,STOMPINGTANTRUM,STONEEDGE,SUBSTITUTE,SWAGGER,SWORDSDANCE,TAUNT,THROATCHOP,THUNDERFANG,THUNDERPUNCH,TOXIC,UPROAR,ZENHEADBUTT
Height = 1.1
Color = Red
Shape = BipedalTail
@@ -2069,8 +1822,8 @@ FormName = Dusk Form
BaseStats = 75,117,65,110,55,65
Abilities = TOUGHCLAWS
HiddenAbilities = TOUGHCLAWS
Moves = 0,CRUSHCLAW,1,SUCKERPUNCH,1,ACCELEROCK,1,QUICKGUARD,1,QUICKATTACK,1,COUNTER,1,ENDURE,1,REVERSAL,1,TAUNT,1,TACKLE,1,LEER,1,SANDATTACK,1,DOUBLETEAM,12,ROCKTHROW,16,HOWL,20,BITE,24,ROCKTOMB,30,ROAR,36,ROCKSLIDE,42,CRUNCH,48,SCARYFACE,54,STEALTHROCK,60,STONEEDGE
TutorMoves = ATTRACT,BRICKBREAK,BULKUP,CAPTIVATE,CLOSECOMBAT,CONFIDE,COVET,CRUNCH,DOUBLETEAM,DRILLRUN,EARTHPOWER,ECHOEDVOICE,ENDEAVOR,ENDURE,FACADE,FIREFANG,FOCUSENERGY,FRUSTRATION,GIGAIMPACT,HIDDENPOWER,HYPERVOICE,IRONDEFENSE,IRONHEAD,IRONTAIL,LASTRESORT,MIMIC,NATURALGIFT,OUTRAGE,PLAYROUGH,PROTECT,PSYCHICFANGS,REST,RETURN,REVERSAL,ROAR,ROCKBLAST,ROCKPOLISH,ROCKSLIDE,ROCKTOMB,ROUND,SANDSTORM,SCARYFACE,SECRETPOWER,SLEEPTALK,SNARL,SNORE,STEALTHROCK,STOMPINGTANTRUM,STONEEDGE,SUBSTITUTE,SWAGGER,SWORDSDANCE,TAILSLAP,TAUNT,THUNDERFANG,TOXIC,WORKUP,ZENHEADBUTT
Moves = 0,THRASH,1,ACCELEROCK,1,COUNTER,1,TACKLE,1,LEER,1,SANDATTACK,1,BITE,4,SANDATTACK,7,BITE,12,HOWL,15,ROCKTHROW,18,ODORSLEUTH,23,ROCKTOMB,26,ROAR,29,STEALTHROCK,34,ROCKSLIDE,37,SCARYFACE,40,CRUNCH,45,ROCKCLIMB,48,STONEEDGE
TutorMoves = ATTRACT,BRICKBREAK,BULKUP,CAPTIVATE,CLOSECOMBAT,CONFIDE,COVET,CRUNCH,DOUBLEEDGE,DOUBLETEAM,DRILLRUN,EARTHPOWER,ECHOEDVOICE,ENDEAVOR,ENDURE,FACADE,FIREFANG,FOCUSENERGY,FRUSTRATION,GIGAIMPACT,HIDDENPOWER,HYPERVOICE,IRONDEFENSE,IRONHEAD,IRONTAIL,LASTRESORT,MIMIC,NATURALGIFT,OUTRAGE,PLAYROUGH,PROTECT,PSYCHICFANGS,REST,RETURN,REVERSAL,ROAR,ROCKBLAST,ROCKPOLISH,ROCKSLIDE,ROCKTOMB,ROUND,SANDSTORM,SCARYFACE,SECRETPOWER,SLEEPTALK,SNARL,SNORE,STEALTHROCK,STOMPINGTANTRUM,STONEEDGE,SUBSTITUTE,SWAGGER,SWORDSDANCE,TAILSLAP,TAUNT,THUNDERFANG,TOXIC,WORKUP,ZENHEADBUTT
Pokedex = Bathed in the setting sun of evening, Lycanroc has undergone a special kind of evolution. An intense fighting spirit underlies its calmness.
Flags = InheritFormFromMother
#-------------------------------
@@ -2296,7 +2049,7 @@ Pokedex = Capable of generating 15,000 volts of electricity, this Pokémon looks
[SINISTEA,1]
FormName = Antique Form
Pokedex = The swirl pattern in this Pokémon's body is its weakness. If it gets stirred, the swirl loses its shape, and Sinistea gets dizzy.
Evolution = POLTEAGEIST,Item,CHIPPEDPOT
Evolutions = POLTEAGEIST,Item,CHIPPEDPOT
#-------------------------------
[POLTEAGEIST,1]
FormName = Antique Form
@@ -2558,17 +2311,3 @@ Color = Black
Shape = Quadruped
Category = High King
Pokedex = Legend says that by using its power to see all events from past to future, this Pokémon saved the creatures of a forest from a meteorite strike.
#-------------------------------
[BASCULEGION,3]
FormName = Female
BaseStats = 120,92,65,78,100,75
Pokedex = It can afflict a target with terrifying illusions that are under its control. The deeper the sadness in its friends' souls, the paler Basculegion becomes.
Generation = 8
Flags = DefaultForm_3,InheritFormWithEverStone
#-------------------------------
[ENAMORUS,1]
FormName = Therian Form
BaseStats = 74,115,110,46,135,100
Abilities = OVERCOAT
Shape = Quadruped
Pokedex = A different guise from its feminine humanoid form. From the clouds, it descends upon those who treat any form of life with disrespect and metes out wrathful, ruthless punishment.

View File

@@ -1070,175 +1070,3 @@ Description = Combines Unnerve and Chilling Neigh Abilities.
[ASONEGRIMNEIGH]
Name = As One
Description = Combines Unnerve and Grim Neigh Abilities.
#-------------------------------
[LINGERINGAROMA]
Name = Lingering Aroma
Description = Contact with this Pokémon spreads this Ability.
#-------------------------------
[SEEDSOWER]
Name = Seed Sower
Description = When the Pokémon is hit, creates Grassy Terrain.
#-------------------------------
[THERMALEXCHANGE]
Name = Thermal Exchange
Description = Raises Attack when hit by a Fire move. Can't be burned.
#-------------------------------
[ANGERSHELL]
Name = Anger Shell
Description = Lowers defences and ups offences/Speed at half HP.
#-------------------------------
[PURIFYINGSALT]
Name = Purifying Salt
Description = Immune to status problems and resists Ghost damage.
#-------------------------------
[WELLBAKEDBODY]
Name = Well-Baked Body
Description = Sharply boosts Defense when hit by Fire moves.
#-------------------------------
[WINDRIDER]
Name = Wind Rider
Description = Boosts Attack if hit or affected by a wind move.
#-------------------------------
[GUARDDOG]
Name = Guard Dog
Description = Can't be forced to switch out. Intimidate ups Attack.
#-------------------------------
[ROCKYPAYLOAD]
Name = Rocky Payload
Description = Powers up Rock-type moves.
#-------------------------------
[WINDPOWER]
Name = Wind Power
Description = Powers up an Electric move if hit by a wind move.
#-------------------------------
[ZEROTOHERO]
Name = Zero to Hero
Description = Transforms into its Hero Form when it switches out.
#-------------------------------
[COMMANDER]
Name = Commander
Description = On entering battle, enters an ally Dodonzo's mouth.
#-------------------------------
[ELECTROMORPHOSIS]
Name = Electromorphosis
Description = Powers up the next Electric move when it is hit.
#-------------------------------
[PROTOSYNTHESIS]
Name = Protosynthesis
Description = Boosts the highest stat in sun or with Booster Energy.
#-------------------------------
[QUARKDRIVE]
Name = Quark Drive
Description = Boosts the highest stat on Electric Terrain.
#-------------------------------
[GOODASGOLD]
Name = Good as Gold
Description = Full immunity to other Pokémon's status moves.
#-------------------------------
[VESSELOFRUIN]
Name = Vessel of Ruin
Description = Lowers the Sp. Atk of all Pokémon except itself.
#-------------------------------
[SWORDOFRUIN]
Name = Sword of Ruin
Description = Lowers the Defense of all Pokémon except itself.
#-------------------------------
[TABLETSOFRUIN]
Name = Tablets of Ruin
Description = Lowers the Attack of all Pokémon except itself.
#-------------------------------
[BEADSOFRUIN]
Name = Beads of Ruin
Description = Lowers the Sp. Def of all Pokémon except itself.
#-------------------------------
[ORICHALCUMPULSE]
Name = Orichalcum Pulse
Description = Causes harsh sunlight and boosts Attack in sunlight.
#-------------------------------
[HADRONENGINE]
Name = Hadron Engine
Description = Creates Electric Terrain and ups Sp. Atk stat on it.
#-------------------------------
[OPPORTUNIST]
Name = Opportunist
Description = Copies boosts when an opponent's stat raises.
#-------------------------------
[CUDCHEW]
Name = Cud Chew
Description = After consuming a Berry, eats it again next turn.
#-------------------------------
[SHARPNESS]
Name = Sharpness
Description = Powers up slicing moves.
#-------------------------------
[SUPREMEOVERLORD]
Name = Supreme Overlord
Description = Raises Attack and Sp. Atk for each defeated ally.
#-------------------------------
[COSTAR]
Name = Costar
Description = On entering battle, copies an ally's stat changes.
#-------------------------------
[TOXICDEBRIS]
Name = Toxic Debris
Description = Scatters poison spikes when hit by physical moves.
#-------------------------------
[ARMORTAIL]
Name = Armor Tail
Description = Prevents opponents from using priority moves.
#-------------------------------
[EARTHEATER]
Name = Earth Eater
Description = Restores HP when hit by a Ground-type move.
#-------------------------------
[MYCELIUMMIGHT]
Name = Mycelium Might
Description = Status moves ignore foe Abilities by acting slowly.
#-------------------------------
[HOSPITALITY]
Name = Hospitality
Description = On entering battle, the ally restores a little HP.
#-------------------------------
[MINDSEYE]
Name = Mind's Eye
Description = Ignores Ghost immunities. Cannot lose accuracy.
#-------------------------------
[EMBODYASPECTSPEED]
Name = Embody Aspect
Description = The Pokémon's shining mask boosts its Speed stat.
#-------------------------------
[EMBODYASPECTATTACK]
Name = Embody Aspect
Description = The Pokémon's shining mask boosts its Attack stat.
#-------------------------------
[EMBODYASPECTSPDEF]
Name = Embody Aspect
Description = The Pokémon's shining mask boosts its Sp. Def stat.
#-------------------------------
[EMBODYASPECTDEFENSE]
Name = Embody Aspect
Description = The Pokémon's shining mask boosts its Defense stat.
#-------------------------------
[TOXICCHAIN]
Name = Toxic Chain
Description = The Pokémon may badly poison any target it hits.
#-------------------------------
[SUPERSWEETSYRUP]
Name = Supersweet Syrup
Description = On entering battle, lowers the foes' evasiveness.
#-------------------------------
[TERASHIFT]
Name = Tera Shift
Description = Transforms into its Terastal Form in battle.
#-------------------------------
[TERASHELL]
Name = Tera Shell
Description = At full HP, damage taken is not very effective.
#-------------------------------
[TERAFORMZERO]
Name = Teraform Zero
Description = Eliminates all effects of weather and terrain.
#-------------------------------
[POISONPUPPETEER]
Name = Poison Puppeteer
Description = Poisoning another Pokémon also causes confusion.

View File

@@ -1,311 +1 @@
# See the documentation on the wiki to learn how to edit this file.
#-------------------------------
[002] # Lappet Town
Water,2
60,TENTACOOL,14,19
30,MANTYKE,15,16
10,REMORAID,14,16
OldRod
100,MAGIKARP,16,19
GoodRod
60,BARBOACH,17,18
20,KRABBY,15,16
20,SHELLDER,16,19
SuperRod
40,CHINCHOU,17,19
40,QWILFISH,16,19
15,CORSOLA,15,18
5,STARYU,15,17
#-------------------------------
[005] # Route 1
Land,21
40,PIDGEY,11,14
40,RATTATA,11,14
9,PIDGEY,11,13
9,RATTATA,11,13
1,PIDGEY,14
1,RATTATA,14
LandNight,21
39,RATTATA,10,14
30,HOOTHOOT,10,13
20,SPINARAK,8,12
9,HOOTHOOT,10,14
1,HOOTHOOT,14
1,RATTATA,15
PokeRadar,20
100,STARLY,12,15
#-------------------------------
[005,1] # Route 1
Land,21
40,PIDGEY,15,18
40,RATTATA,14,18
10,SENTRET,13,17
5,PIDGEY,14,16
5,RATTATA,13,16
LandNight,21
40,RATTATA,14,18
30,HOOTHOOT,14,17
20,SPINARAK,12,16
10,CLEFAIRY,11,15
#-------------------------------
[021] # Route 2
Land,21
50,RATTATA,12,15
30,POOCHYENA,11,15
10,SHINX,10,12
10,SHINX,10,11
Water,2
60,MAGIKARP,7,10
30,GOLDEEN,11,14
10,STARYU,12,15
OldRod
70,MAGIKARP,7,10
30,MAGIKARP,9,15
GoodRod
60,GOLDEEN,12,14
20,FINNEON,12,15
20,MAGIKARP,12,17
SuperRod
40,FINNEON,12,15
40,GOLDEEN,12,14
15,STARYU,12,15
5,STARYU,14,17
HeadbuttLow
50,PINECO,11,13
30,LEDYBA,6,8
19,SPINARAK,9,12
1,MUNCHLAX,11,14
HeadbuttHigh
50,PINECO,11,13
30,WURMPLE,6,8
20,SPINARAK,9,12
PokeRadar,10
100,STANTLER,14
#-------------------------------
[028] # Natural Park
Land,21
20,CATERPIE,10
20,SUNKERN,12
20,WEEDLE,10
15,PIDGEY,10,14
15,PIDGEY,12,14
5,KAKUNA,10
5,METAPOD,10
LandNight,21
30,HOOTHOOT,10,14
30,SPINARAK,10,15
20,PINECO,9,13
10,DROWZEE,9,15
10,NATU,12,14
LandMorning,21
25,CATERPIE,10,12
25,WEEDLE,10,12
20,PIDGEY,10,14
15,KAKUNA,10
15,METAPOD,10
BugContest,21
20,CATERPIE,7,18
20,WEEDLE,7,18
10,KAKUNA,9,18
10,METAPOD,9,18
10,PARAS,10,17
10,VENONAT,10,16
5,BEEDRILL,12,15
5,BUTTERFREE,12,15
5,PINSIR,13,14
5,SCYTHER,13,14
PokeRadar,40
50,BUTTERFREE,15,18
50,BEEDRILL,15,18
#-------------------------------
[031] # Route 3
Land,21
30,NIDORANfE,12,15
30,NIDORANmA,12,15
20,PIKACHU,14,17
10,EEVEE,15
10,PONYTA,13,15
Water,2
60,SURSKIT,13,14
35,LOTAD,14
5,LOTAD,15
OldRod
70,MAGIKARP,6,11
30,MAGIKARP,10,17
GoodRod
60,POLIWAG,12,15
20,PSYDUCK,11,14
20,WOOPER,13,17
SuperRod
40,CHINCHOU,11,12
40,REMORAID,12,14
20,LUVDISC,10,16
RockSmash,50
60,NOSEPASS,13,14
40,GEODUDE,12,15
HeadbuttLow
30,PINECO,14,17
25,COMBEE,15,17
20,PINECO,14,16
10,HERACROSS,16,18
9,HERACROSS,16,17
5,COMBEE,15,16
1,MUNCHLAX,13,18
HeadbuttHigh
50,SEEDOT,14,17
30,SHROOMISH,14,17
20,BURMY,12,15
#-------------------------------
[034] # Ice Cave
Cave,5
40,SWINUB,16,18
20,SNEASEL,14,16
20,SNORUNT,12,15
10,SMOOCHUM,11,14
10,SNOVER,14
#-------------------------------
[039] # Route 4
Land,21
50,SHELLOS_1,12,15
40,GRIMER,13,15
10,MURKROW,12,14
#-------------------------------
[041] # Route 5
Land,21
50,GRIMER,13,15
40,SPEAROW,13,16
10,SLUGMA,13,14
#-------------------------------
[044] # Route 6
Land,21
50,SHELLOS_1,12,15
40,GRIMER,13,15
10,MURKROW,12,14
#-------------------------------
[047] # Route 7
Land,21
50,SHELLOS,12,15
30,BIDOOF,14,17
10,MURKROW,12,14
10,WURMPLE,9,12
RockSmash,50
90,NOSEPASS,13,14
10,GEODUDE,12,15
#-------------------------------
[049] # Rock Cave 1F
Cave,5
20,MAGNETON,14,16
20,MAGNETON,14,17
20,NOSEPASS,14,15
20,NOSEPASS,13,14
10,GEODUDE,13,15
10,MAWILE,14,16
#-------------------------------
[050] # Rock Cave B1F
Cave,5
20,MAGNETON,14,16
20,MAGNETON,14,17
20,NOSEPASS,14,15
20,NOSEPASS,13,14
10,BURMY,14,16
10,GEODUDE,13,15
#-------------------------------
[051] # Dungeon
Cave,5
20,CHINGLING,1
20,CLEFFA,1
20,IGGLYBUFF,1
20,PICHU,1
10,RIOLU,1
10,TYROGUE,1
#-------------------------------
[066] # Safari Zone outside
Land,21
20,ABRA,12,15
20,DODUO,13,15
20,NIDORANfE,15,16
20,NIDORANmA,15,16
10,HOPPIP,13,17
10,TANGELA,14,16
#-------------------------------
[068] # Safari Zone
Land,21
20,EXEGGCUTE,15,18
20,RHYHORN,16,18
10,AIPOM,14,17
10,GIRAFARIG,16,17
10,VENONAT,15,17
10,VENONAT,15,18
5,HERACROSS,15,17
5,TAUROS,15,16
4,PINSIR,16
4,SCYTHER,16
1,CHANSEY,17
1,KANGASKHAN,19
Water,2
60,PSYDUCK,16,18
30,MARILL,15,18
5,BUIZEL,15,17
5,SLOWPOKE,14,16
OldRod
70,MAGIKARP,17,21
30,MAGIKARP,17,20
GoodRod
60,MAGIKARP,16,20
20,FEEBAS,16,20
20,POLIWAG,17,18
SuperRod
40,GOLDEEN,16,18
40,REMORAID,17,19
15,CARVANHA,16,17
4,FINNEON,15,18
1,DRATINI,17
#-------------------------------
[069] # Route 8
Land,21
20,MAREEP,16,18
20,ODDISH,15,17
13,BONSLY,14,16
10,DITTO,15,17
10,DITTO,16,18
10,LOTAD,15,18
10,LOTAD,15,17
5,BONSLY,14,17
1,BONSLY,15,16
1,BONSLY,15
Water,2
60,TENTACOOL,14,19
30,MANTYKE,15,16
10,REMORAID,14,16
OldRod
100,MAGIKARP,16,19
GoodRod
60,BARBOACH,17,18
20,KRABBY,15,16
20,SHELLDER,16,19
SuperRod
40,CHINCHOU,17,19
40,QWILFISH,16,19
15,CORSOLA,15,18
5,STARYU,15,17
#-------------------------------
[070] # Route 8 underwater
Land,21
20,CHINCHOU,17,21
20,CLAMPERL,18,20
20,SHELLDER,18,20
10,CLAMPERL,18,19
10,CORSOLA,17,20
10,RELICANTH,16,19
10,SHELLDER,18,19
#-------------------------------
[075] # Tiall Region
Land,21
20,GEODUDE_1,11,14
20,RATTATA_1,11,14
10,CUBONE,11,14
10,DIGLETT_1,11,14
10,MEOWTH_1,11,14
10,PIKACHU,11,14
10,SANDSHREW_1,11,14
10,VULPIX_1,11,14


File diff suppressed because it is too large Load Diff

View File

@@ -1,40 +1,12 @@
# See the documentation on the wiki to learn how to edit this file.
#-------------------------------
# Route 5 (41) - Route 4 Cycling Road (40)
41,N,0,40,S,0
# Route 5 (41) - Route 6 Cycling Road (45)
41,S,6,45,N,0
# Route 6 (44) - Route 1 (5)
44,S,43,5,N,0
# Safari Zone outside (66) - Route 1 (5)
66,N,18,5,S,0
# Cedolan City (7) - Route 1 (5)
7,S,0,5,N,2
# Lappet Town (2) - Route 1 (5)
2,N,0,5,S,4
# Cedolan City (7) - Route 6 (44)
7,W,5,44,E,0
# Lappet Town (2) - Safari Zone outside (66)
2,W,0,66,E,0
# Route 8 (69) - Safari Zone outside (66)
69,N,0,66,S,10
# Ingido Plateau outside (35) - Route 4 (39)
35,W,11,39,E,0
# Cedolan City (7) - Lerucean Town (23)
7,E,0,23,W,78
# Route 3 (31) - Lerucean Town (23)
31,S,32,23,N,0
# Route 2 (21) - Lerucean Town (23)
21,E,0,23,W,1
# Route 7 (47) - Cedolan City (7)
47,W,0,7,E,0
# Route 2 (21) - Cedolan City (7)
21,S,0,7,N,21
# Route 3 (31) - Ingido Plateau outside (35)
31,W,0,35,E,10
# Route 8 (69) - Lappet Town (2)
69,N,12,2,S,0
# Route 7 (47) - Battle Frontier (52)
47,E,8,52,W,0
# Route 2 (21) - Route 7 (47)
21,E,77,47,W,0
# Route 102 (10) - Petalburg Town (7)
10,West,0,7,East,18
# Route 104 (South) (12) - Petalburg Town (7)
12,East,16,7,West,0
# Oldale Town (8) - Route 102 (10)
8,West,2,10,East,0
# Route 101 (5) - Oldale Town (8)
5,North,2,8,South,0
# Route 103 (West) (11) - Oldale Town (8)
11,South,3,8,North,0
# Littleroot Town (9) - Route 101 (5)
9,North,0,5,South,0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -3,77 +3,34 @@
[0]
Name = Essen
Filename = mapRegion0.png
PointSize = 16,16
Size = 30,20
Point = 13,12,Lappet Town
Image = image_lappet_town
Description = \PN's house\nProfessor Oak's lab
FlySpot = 2,8,8
Point = 13,12,Lappet Town,Oak's Lab,2,8,8
Point = 13,11,Route 1
Description = Kurt's house
Point = 13,10,Cedolan City
Image = image_cedolan_city
Description = Cedolan Dept. Store\nCedolan Gym\nMove Maniac House
FlySpot = 7,47,11
FlyIconOffset = 8,0
Point = 14,10,Cedolan City
Image = image_cedolan_city
Description = Game Corner\nPokémon Institute
FlySpot = 7,47,11
HideFlyIcon = true
Point = 13,10,Cedolan City,Cedolan Dept. Store,7,47,11
Point = 14,10,Cedolan City,,7,47,11
Point = 14,9,Route 2
Description = Bridges
Point = 14,8,Route 2
Description = Bridges
Point = 15,8,Lerucean Town
Image = image_lerucean_town
Description = Day Care Center\nPokémon Fan Club\nLerucean Market
FlySpot = 23,11,15
Point = 15,8,Lerucean Town,,23,11,15
Point = 16,8,Natural Park
Description = A Bug Catching Contest is held here every Tuesday, Thursday and Saturday.
Point = 15,7,Route 3
Point = 15,6,Route 3
Description = Ice Cave
Point = 15,6,Route 3,Ice Cave
Point = 14,6,Route 3
Description = Examples of trainer battles.
Point = 13,6,Ingido Plateau
Image = image_ingido_plateau
Description = Pokémon League
FlySpot = 35,17,7
Point = 13,6,Ingido Plateau,,35,17,7
Point = 12,6,Route 4
Point = 11,6,Route 4
Description = Cycle Road
Point = 11,7,Route 5
Description = Cycle Road
Point = 11,8,Route 5
Description = Cycle Road
Point = 11,9,Route 5
Description = Cycle Road
Point = 11,7,Route 5,Cycle Road
Point = 11,8,Route 5,Cycle Road
Point = 11,9,Route 5,Cycle Road
Point = 11,10,Route 6
Description = Cycle Road
Point = 12,10,Route 6
Point = 15,10,Route 7
Point = 16,10,Route 7
Description = Rock Cave
Point = 17,10,Battle Frontier
Image = image_battle_frontier
Description = Battle Palace\nBattle Tower\nBattle Arena\nBattle Factory
FlySpot = 52,17,14
Point = 16,10,Route 7,Rock Cave
Point = 17,10,Battle Frontier,,52,17,14
Point = 12,12,Safari Zone
Description = Challenge yourself by catching Pokémon without using your own.
Point = 13,13,Route 8
Image = image_route_8
Description = Harbor\nDiving area
Point = 18,17,Berth Island
Description = Four mysterious meteorites can be found here.
Switch = 51
Point = 22,16,Faraday Island
Description = A blue Mew can be found here every so often.
Switch = 52
Point = 13,13,Route 8,Diving area
Point = 18,17,Berth Island,,,,,51
Point = 22,16,Faraday Island,,,,,52
#-------------------------------
[1]
Name = Tiall
Filename = mapRegion1.png
PointSize = 16,16
Size = 30,20
Point = 13,16,Here

View File

@@ -80,7 +80,6 @@ BaseMoney = 48
Name = Fisherman
Gender = Male
BaseMoney = 32
PokeBall = LUREBALL
#-------------------------------
[GAMBLER]
Name = Gambler
@@ -92,7 +91,6 @@ SkillLevel = 32
Name = Gentleman
Gender = Male
BaseMoney = 72
PokeBall = LUXURYBALL
#-------------------------------
[HIKER]
Name = Hiker
@@ -109,7 +107,6 @@ Name = Lady
Gender = Female
BaseMoney = 160
SkillLevel = 72
PokeBall = LUXURYBALL
#-------------------------------
[PAINTER]
Name = Painter
@@ -125,7 +122,6 @@ BaseMoney = 64
Name = Pokémon Breeder
Gender = Female
BaseMoney = 48
PokeBall = FRIENDBALL
#-------------------------------
[PROFESSOR]
Name = Professor
@@ -151,7 +147,6 @@ BaseMoney = 32
Name = Scientist
Gender = Male
BaseMoney = 48
PokeBall = REPEATBALL
#-------------------------------
[SUPERNERD]
Name = Super Nerd
@@ -167,7 +162,6 @@ BaseMoney = 40
Name = Black Belt
Gender = Male
BaseMoney = 32
PokeBall = ULTRABALL
#-------------------------------
[CRUSHGIRL]
Name = Crush Girl
@@ -188,13 +182,11 @@ BaseMoney = 16
Name = Cool Trainer
Gender = Male
BaseMoney = 60
PokeBall = ULTRABALL
#-------------------------------
[COOLTRAINER_F]
Name = Cool Trainer
Gender = Female
BaseMoney = 60
PokeBall = ULTRABALL
#-------------------------------
[YOUNGSTER]
Name = Youngster
@@ -231,28 +223,24 @@ Name = Swimmer
Gender = Male
BaseMoney = 16
SkillLevel = 32
PokeBall = DIVEBALL
#-------------------------------
[SWIMMER_F]
Name = Swimmer
Gender = Female
BaseMoney = 16
SkillLevel = 32
PokeBall = DIVEBALL
#-------------------------------
[SWIMMER2_M]
Name = Swimmer
Gender = Male
BaseMoney = 16
SkillLevel = 32
PokeBall = DIVEBALL
#-------------------------------
[SWIMMER2_F]
Name = Swimmer
Gender = Female
BaseMoney = 16
SkillLevel = 32
PokeBall = DIVEBALL
#-------------------------------
[TUBER_M]
Name = Tuber
@@ -283,7 +271,6 @@ Name = Cool Couple
Gender = Unknown
BaseMoney = 72
SkillLevel = 48
PokeBall = ULTRABALL
#-------------------------------
[CRUSHKIN]
Name = Crush Kin
@@ -295,7 +282,6 @@ Name = Sis and Bro
Gender = Unknown
BaseMoney = 16
SkillLevel = 48
PokeBall = DIVEBALL
#-------------------------------
[TWINS]
Name = Twins
@@ -385,7 +371,6 @@ Gender = Female
BaseMoney = 100
BattleBGM = Battle Elite
VictoryBGM = Battle victory leader
PokeBall = ULTRABALL
#-------------------------------
[ELITEFOUR_Bruno]
Name = Elite Four
@@ -393,7 +378,6 @@ Gender = Male
BaseMoney = 100
BattleBGM = Battle Elite
VictoryBGM = Battle victory leader
PokeBall = ULTRABALL
#-------------------------------
[ELITEFOUR_Agatha]
Name = Elite Four
@@ -401,7 +385,6 @@ Gender = Female
BaseMoney = 100
BattleBGM = Battle Elite
VictoryBGM = Battle victory leader
PokeBall = ULTRABALL
#-------------------------------
[ELITEFOUR_Lance]
Name = Elite Four
@@ -409,7 +392,6 @@ Gender = Male
BaseMoney = 100
BattleBGM = Battle Elite
VictoryBGM = Battle victory leader
PokeBall = ULTRABALL
#-------------------------------
[CHAMPION]
Name = Champion
@@ -417,4 +399,3 @@ Gender = Male
BaseMoney = 100
BattleBGM = Battle Champion
VictoryBGM = Battle victory leader
PokeBall = ULTRABALL