Rearranged some script files

This commit is contained in:
Maruno17
2020-09-05 22:34:32 +01:00
parent 5d3189174c
commit 5073f86190
188 changed files with 250 additions and 239 deletions

View File

@@ -0,0 +1,966 @@
#===============================================================================
# Item data
#===============================================================================
ITEM_ID = 0
ITEM_NAME = 1
ITEM_PLURAL = 2
ITEM_POCKET = 3
ITEM_PRICE = 4
ITEM_DESCRIPTION = 5
ITEM_FIELD_USE = 6
ITEM_BATTLE_USE = 7
ITEM_TYPE = 8
ITEM_MACHINE = 9
class PokemonTemp
attr_accessor :itemsData
end
def pbLoadItemsData
$PokemonTemp = PokemonTemp.new if !$PokemonTemp
if !$PokemonTemp.itemsData
$PokemonTemp.itemsData = load_data("Data/items.dat") || []
end
return $PokemonTemp.itemsData
end
def pbGetItemData(item,itemDataType)
item = getID(PBItems,item)
itemsData = pbLoadItemsData
return itemsData[item][itemDataType] if itemsData[item]
return nil
end
alias __itemsData__pbClearData pbClearData
def pbClearData
$PokemonTemp.itemsData = nil if $PokemonTemp
__itemsData__pbClearData
end
def pbGetPocket(item)
ret = pbGetItemData(item,ITEM_POCKET)
return ret || 0
end
def pbGetPrice(item)
ret = pbGetItemData(item,ITEM_PRICE)
return ret || 0
end
def pbGetMachine(item)
ret = pbGetItemData(item,ITEM_MACHINE)
return ret || 0
end
def pbIsTechnicalMachine?(item)
ret = pbGetItemData(item,ITEM_FIELD_USE)
return ret && ret==3
end
def pbIsHiddenMachine?(item)
ret = pbGetItemData(item,ITEM_FIELD_USE)
return ret && ret==4
end
def pbIsMachine?(item)
ret = pbGetItemData(item,ITEM_FIELD_USE)
return ret && (ret==3 || ret==4)
end
def pbIsMail?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && (ret==1 || ret==2)
end
def pbIsMailWithPokemonIcons?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && ret==2
end
def pbIsPokeBall?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && (ret==3 || ret==4)
end
def pbIsSnagBall?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && (ret==3 || (ret==4 && $PokemonGlobal.snagMachine))
end
def pbIsBerry?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && ret==5
end
def pbIsKeyItem?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && ret==6
end
def pbIsEvolutionStone?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && ret==7
end
def pbIsFossil?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && ret==8
end
def pbIsApricorn?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && ret==9
end
def pbIsGem?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && ret==10
end
def pbIsMulch?(item)
ret = pbGetItemData(item,ITEM_TYPE)
return ret && ret==11
end
def pbIsMegaStone?(item) # Does NOT include Red Orb/Blue Orb
ret = pbGetItemData(item,ITEM_TYPE)
return ret && ret==12
end
# Important items can't be sold, given to hold, or tossed.
def pbIsImportantItem?(item)
itemData = pbLoadItemsData[getID(PBItems,item)]
return false if !itemData
return true if itemData[ITEM_TYPE] && itemData[ITEM_TYPE]==6 # Key item
return true if itemData[ITEM_FIELD_USE] && itemData[ITEM_FIELD_USE]==4 # HM
return true if itemData[ITEM_FIELD_USE] && itemData[ITEM_FIELD_USE]==3 && INFINITE_TMS # TM
return false
end
def pbCanHoldItem?(item)
return !pbIsImportantItem?(item)
end
def pbCanRegisterItem?(item)
return ItemHandlers.hasUseInFieldHandler(item)
end
def pbCanUseOnPokemon?(item)
return ItemHandlers.hasUseOnPokemon(item) || pbIsMachine?(item)
end
def pbIsHiddenMove?(move)
itemsData = pbLoadItemsData
return false if !itemsData
for i in 0...itemsData.length
next if !pbIsHiddenMachine?(i)
atk = pbGetMachine(i)
return true if move==atk
end
return false
end
def pbIsUnlosableItem?(item,species,ability)
return false if isConst?(species,PBSpecies,:ARCEUS) &&
!isConst?(ability,PBAbilities,:MULTITYPE)
return false if isConst?(species,PBSpecies,:SILVALLY) &&
!isConst?(ability,PBAbilities,:RKSSYSTEM)
combos = {
:ARCEUS => [:FISTPLATE,:FIGHTINIUMZ,
:SKYPLATE,:FLYINIUMZ,
:TOXICPLATE,:POISONIUMZ,
:EARTHPLATE,:GROUNDIUMZ,
:STONEPLATE,:ROCKIUMZ,
:INSECTPLATE,:BUGINIUMZ,
:SPOOKYPLATE,:GHOSTIUMZ,
:IRONPLATE,:STEELIUMZ,
:FLAMEPLATE,:FIRIUMZ,
:SPLASHPLATE,:WATERIUMZ,
:MEADOWPLATE,:GRASSIUMZ,
:ZAPPLATE,:ELECTRIUMZ,
:MINDPLATE,:PSYCHIUMZ,
:ICICLEPLATE,:ICIUMZ,
:DRACOPLATE,:DRAGONIUMZ,
:DREADPLATE,:DARKINIUMZ,
:PIXIEPLATE,:FAIRIUMZ],
:SILVALLY => [:FIGHTINGMEMORY,
:FLYINGMEMORY,
:POISONMEMORY,
:GROUNDMEMORY,
:ROCKMEMORY,
:BUGMEMORY,
:GHOSTMEMORY,
:STEELMEMORY,
:FIREMEMORY,
:WATERMEMORY,
:GRASSMEMORY,
:ELECTRICMEMORY,
:PSYCHICMEMORY,
:ICEMEMORY,
:DRAGONMEMORY,
:DARKMEMORY,
:FAIRYMEMORY],
:GIRATINA => [:GRISEOUSORB],
:GENESECT => [:BURNDRIVE,:CHILLDRIVE,:DOUSEDRIVE,:SHOCKDRIVE],
:KYOGRE => [:BLUEORB],
:GROUDON => [:REDORB]
}
ret = false
combos.each do |comboSpecies, items|
next if !isConst?(species,PBSpecies,comboSpecies)
items.each { |i| return true if isConst?(item,PBItems,i) }
break
end
return false
end
#===============================================================================
# ItemHandlers
#===============================================================================
module ItemHandlers
UseText = ItemHandlerHash.new
UseFromBag = ItemHandlerHash.new
ConfirmUseInField = ItemHandlerHash.new
UseInField = ItemHandlerHash.new
UseOnPokemon = ItemHandlerHash.new
CanUseInBattle = ItemHandlerHash.new
UseInBattle = ItemHandlerHash.new
BattleUseOnBattler = ItemHandlerHash.new
BattleUseOnPokemon = ItemHandlerHash.new
def self.hasUseText(item)
return UseText[item]!=nil
end
def self.hasOutHandler(item) # Shows "Use" option in Bag
return UseFromBag[item]!=nil || UseInField[item]!=nil || UseOnPokemon[item]!=nil
end
def self.hasUseInFieldHandler(item) # Shows "Register" option in Bag
return UseInField[item]!=nil
end
def self.hasUseOnPokemon(item)
return UseOnPokemon[item]!=nil
end
def self.hasUseInBattle(item)
return UseInBattle[item]!=nil
end
def self.hasBattleUseOnBattler(item)
return BattleUseOnBattler[item]!=nil
end
def self.hasBattleUseOnPokemon(item)
return BattleUseOnPokemon[item]!=nil
end
# Returns text to display instead of "Use"
def self.getUseText(item)
return UseText.trigger(item)
end
# Return value:
# 0 - Item not used
# 1 - Item used, don't end screen
# 2 - Item used, end screen
# 3 - Item used, don't end screen, consume item
# 4 - Item used, end screen, consume item
def self.triggerUseFromBag(item)
return UseFromBag.trigger(item) if UseFromBag[item]
# No UseFromBag handler exists; check the UseInField handler if present
return UseInField.trigger(item) if UseInField[item]
return 0
end
# Returns whether item can be used
def self.triggerConfirmUseInField(item)
return true if !ConfirmUseInField[item]
return ConfirmUseInField.trigger(item)
end
# Return value:
# -1 - Item effect not found
# 0 - Item not used
# 1 - Item used
# 3 - Item used, consume item
def self.triggerUseInField(item)
return -1 if !UseInField[item]
return UseInField.trigger(item)
end
# Returns whether item was used
def self.triggerUseOnPokemon(item,pkmn,scene)
return false if !UseOnPokemon[item]
return UseOnPokemon.trigger(item,pkmn,scene)
end
def self.triggerCanUseInBattle(item,pkmn,battler,move,firstAction,battle,scene,showMessages=true)
return true if !CanUseInBattle[item] # Can use the item by default
return CanUseInBattle.trigger(item,pkmn,battler,move,firstAction,battle,scene,showMessages)
end
def self.triggerUseInBattle(item,battler,battle)
UseInBattle.trigger(item,battler,battle)
end
# Returns whether item was used
def self.triggerBattleUseOnBattler(item,battler,scene)
return false if !BattleUseOnBattler[item]
return BattleUseOnBattler.trigger(item,battler,scene)
end
# Returns whether item was used
def self.triggerBattleUseOnPokemon(item,pkmn,battler,choices,scene)
return false if !BattleUseOnPokemon[item]
return BattleUseOnPokemon.trigger(item,pkmn,battler,choices,scene)
end
end
#===============================================================================
# Change a Pokémon's level
#===============================================================================
def pbChangeLevel(pkmn,newlevel,scene)
newlevel = 1 if newlevel<1
mLevel = PBExperience.maxLevel
newlevel = mLevel if newlevel>mLevel
if pkmn.level==newlevel
pbMessage(_INTL("{1}'s level remained unchanged.",pkmn.name))
elsif pkmn.level>newlevel
attackdiff = pkmn.attack
defensediff = pkmn.defense
speeddiff = pkmn.speed
spatkdiff = pkmn.spatk
spdefdiff = pkmn.spdef
totalhpdiff = pkmn.totalhp
pkmn.level = newlevel
pkmn.calcStats
scene.pbRefresh
pbMessage(_INTL("{1} dropped to Lv. {2}!",pkmn.name,pkmn.level))
attackdiff = pkmn.attack-attackdiff
defensediff = pkmn.defense-defensediff
speeddiff = pkmn.speed-speeddiff
spatkdiff = pkmn.spatk-spatkdiff
spdefdiff = pkmn.spdef-spdefdiff
totalhpdiff = pkmn.totalhp-totalhpdiff
pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
totalhpdiff,attackdiff,defensediff,spatkdiff,spdefdiff,speeddiff))
pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
pkmn.totalhp,pkmn.attack,pkmn.defense,pkmn.spatk,pkmn.spdef,pkmn.speed))
else
attackdiff = pkmn.attack
defensediff = pkmn.defense
speeddiff = pkmn.speed
spatkdiff = pkmn.spatk
spdefdiff = pkmn.spdef
totalhpdiff = pkmn.totalhp
oldlevel = pkmn.level
pkmn.level = newlevel
pkmn.changeHappiness("vitamin")
pkmn.calcStats
scene.pbRefresh
pbMessage(_INTL("{1} grew to Lv. {2}!",pkmn.name,pkmn.level))
attackdiff = pkmn.attack-attackdiff
defensediff = pkmn.defense-defensediff
speeddiff = pkmn.speed-speeddiff
spatkdiff = pkmn.spatk-spatkdiff
spdefdiff = pkmn.spdef-spdefdiff
totalhpdiff = pkmn.totalhp-totalhpdiff
pbTopRightWindow(_INTL("Max. HP<r>+{1}\r\nAttack<r>+{2}\r\nDefense<r>+{3}\r\nSp. Atk<r>+{4}\r\nSp. Def<r>+{5}\r\nSpeed<r>+{6}",
totalhpdiff,attackdiff,defensediff,spatkdiff,spdefdiff,speeddiff))
pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
pkmn.totalhp,pkmn.attack,pkmn.defense,pkmn.spatk,pkmn.spdef,pkmn.speed))
# Learn new moves upon level up
movelist = pkmn.getMoveList
for i in movelist
next if i[0]!=pkmn.level
pbLearnMove(pkmn,i[1],true)
end
# Check for evolution
newspecies = pbCheckEvolution(pkmn)
if newspecies>0
pbFadeOutInWithMusic {
evo = PokemonEvolutionScene.new
evo.pbStartScreen(pkmn,newspecies)
evo.pbEvolution
evo.pbEndScreen
}
end
end
end
def pbTopRightWindow(text)
window = Window_AdvancedTextPokemon.new(text)
window.width = 198
window.x = Graphics.width-window.width
window.y = 0
window.z = 99999
pbPlayDecisionSE
loop do
Graphics.update
Input.update
window.update
break if Input.trigger?(Input::C)
end
window.dispose
end
#===============================================================================
# Restore HP
#===============================================================================
def pbItemRestoreHP(pkmn,restoreHP)
newHP = pkmn.hp+restoreHP
newHP = pkmn.totalhp if newHP>pkmn.totalhp
hpGain = newHP-pkmn.hp
pkmn.hp = newHP
return hpGain
end
def pbHPItem(pkmn,restoreHP,scene)
if !pkmn.able? || pkmn.hp==pkmn.totalhp
scene.pbDisplay(_INTL("It won't have any effect."))
return false
end
hpGain = pbItemRestoreHP(pkmn,restoreHP)
scene.pbRefresh
scene.pbDisplay(_INTL("{1}'s HP was restored by {2} points.",pkmn.name,hpGain))
return true
end
def pbBattleHPItem(pkmn,battler,restoreHP,scene)
if battler
if battler.pbRecoverHP(restoreHP)>0
scene.pbDisplay(_INTL("{1}'s HP was restored.",battler.pbThis))
end
else
if pbItemRestoreHP(pkmn,restoreHP)>0
scene.pbDisplay(_INTL("{1}'s HP was restored.",pkmn.name))
end
end
return true
end
#===============================================================================
# Restore PP
#===============================================================================
def pbRestorePP(pkmn,idxMove,pp)
return 0 if !pkmn.moves[idxMove] || pkmn.moves[idxMove].id==0
return 0 if pkmn.moves[idxMove].totalpp<=0
oldpp = pkmn.moves[idxMove].pp
newpp = pkmn.moves[idxMove].pp+pp
newpp = pkmn.moves[idxMove].totalpp if newpp>pkmn.moves[idxMove].totalpp
pkmn.moves[idxMove].pp = newpp
return newpp-oldpp
end
def pbBattleRestorePP(pkmn,battler,idxMove,pp)
if pbRestorePP(pkmn,idxMove,pp)>0
if battler && !battler.effects[PBEffects::Transform] &&
battler.moves[idxMove] && battler.moves[idxMove].id==pkmn.moves[idxMove].id
battler.pbSetPP(battler.moves[idxMove],pkmn.moves[idxMove].pp)
end
end
return ret
end
#===============================================================================
# Change EVs
#===============================================================================
def pbJustRaiseEffortValues(pkmn,ev,evgain)
totalev = 0
for i in 0...6
totalev += pkmn.ev[i]
end
if totalev+evgain>PokeBattle_Pokemon::EV_LIMIT
evgain = PokeBattle_Pokemon::EV_LIMIT-totalev
end
if pkmn.ev[ev]+evgain>PokeBattle_Pokemon::EV_STAT_LIMIT
evgain = PokeBattle_Pokemon::EV_STAT_LIMIT-pkmn.ev[ev]
end
if evgain>0
pkmn.ev[ev] += evgain
pkmn.calcStats
end
return evgain
end
def pbRaiseEffortValues(pkmn,ev,evgain=10,evlimit=true)
return 0 if evlimit && pkmn.ev[ev]>=100
totalev = 0
for i in 0...6
totalev += pkmn.ev[i]
end
if totalev+evgain>PokeBattle_Pokemon::EV_LIMIT
evgain = PokeBattle_Pokemon::EV_LIMIT-totalev
end
if pkmn.ev[ev]+evgain>PokeBattle_Pokemon::EV_STAT_LIMIT
evgain = PokeBattle_Pokemon::EV_STAT_LIMIT-pkmn.ev[ev]
end
if evlimit && pkmn.ev[ev]+evgain>100
evgain = 100-pkmn.ev[ev]
end
if evgain>0
pkmn.ev[ev] += evgain
pkmn.calcStats
end
return evgain
end
def pbRaiseHappinessAndLowerEV(pkmn,scene,ev,messages)
h = pkmn.happiness<255
e = pkmn.ev[ev]>0
if !h && !e
scene.pbDisplay(_INTL("It won't have any effect."))
return false
end
if h
pkmn.changeHappiness("evberry")
end
if e
pkmn.ev[ev] -= 10
pkmn.ev[ev] = 0 if pkmn.ev[ev]<0
pkmn.calcStats
end
scene.pbRefresh
scene.pbDisplay(messages[2-(h ? 0 : 2)-(e ? 0 : 1)])
return true
end
#===============================================================================
# Battle items
#===============================================================================
def pbBattleItemCanCureStatus?(status,pkmn,scene,showMessages)
if !pkmn.able? || pkmn.status!=status
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
return false
end
return true
end
def pbBattleItemCanRaiseStat?(stat,battler,scene,showMessages)
if !battler || !battler.pbCanRaiseStatStage?(stat,battler)
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
return false
end
return true
end
#===============================================================================
# Decide whether the player is able to ride/dismount their Bicycle
#===============================================================================
def pbBikeCheck
if $PokemonGlobal.surfing ||
(!$PokemonGlobal.bicycle && PBTerrain.onlyWalk?(pbGetTerrainTag))
pbMessage(_INTL("Can't use that here."))
return false
end
if $game_player.pbHasDependentEvents?
pbMessage(_INTL("It can't be used when you have someone with you."))
return false
end
if $PokemonGlobal.bicycle
if pbGetMetadata($game_map.map_id,MetadataBicycleAlways)
pbMessage(_INTL("You can't dismount your Bike here."))
return false
end
return true
end
val = pbGetMetadata($game_map.map_id,MetadataBicycle)
val = pbGetMetadata($game_map.map_id,MetadataOutdoor) if val==nil
if !val
pbMessage(_INTL("Can't use that here."))
return false
end
return true
end
#===============================================================================
# Find the closest hidden item (for Iremfinder)
#===============================================================================
def pbClosestHiddenItem
result = []
playerX = $game_player.x
playerY = $game_player.y
for event in $game_map.events.values
next if !event.name[/hiddenitem/i]
next if (playerX-event.x).abs>=8
next if (playerY-event.y).abs>=6
next if $game_self_switches[[$game_map.map_id,event.id,"A"]]
result.push(event)
end
return nil if result.length==0
ret = nil
retmin = 0
for event in result
dist = (playerX-event.x).abs+(playerY-event.y).abs
next if ret && retmin<=dist
ret = event
retmin = dist
end
return ret
end
#===============================================================================
# Teach and forget a move
#===============================================================================
def pbLearnMove(pkmn,move,ignoreifknown=false,bymachine=false,&block)
return false if !pkmn
movename = PBMoves.getName(move)
if pkmn.egg? && !$DEBUG
pbMessage(_INTL("Eggs can't be taught any moves."),&block)
return false
end
if pkmn.shadowPokemon?
pbMessage(_INTL("Shadow Pokémon can't be taught any moves."),&block)
return false
end
pkmnname = pkmn.name
if pkmn.hasMove?(move)
pbMessage(_INTL("{1} already knows {2}.",pkmnname,movename),&block) if !ignoreifknown
return false
end
if pkmn.numMoves<4
pkmn.pbLearnMove(move)
pbMessage(_INTL("\\se[]{1} learned {2}!\\se[Pkmn move learnt]",pkmnname,movename),&block)
return true
end
loop do
pbMessage(_INTL("{1} wants to learn {2}, but it already knows four moves.\1",pkmnname,movename),&block) if !bymachine
pbMessage(_INTL("Please choose a move that will be replaced with {1}.",movename),&block)
forgetmove = pbForgetMove(pkmn,move)
if forgetmove>=0
oldmovename = PBMoves.getName(pkmn.moves[forgetmove].id)
oldmovepp = pkmn.moves[forgetmove].pp
pkmn.moves[forgetmove] = PBMove.new(move) # Replaces current/total PP
if bymachine && !NEWEST_BATTLE_MECHANICS
pkmn.moves[forgetmove].pp = [oldmovepp,pkmn.moves[forgetmove].totalpp].min
end
pbMessage(_INTL("1,\\wt[16] 2, and\\wt[16]...\\wt[16] ...\\wt[16] ... Ta-da!\\se[Battle ball drop]\1"),&block)
pbMessage(_INTL("{1} forgot how to use {2}.\\nAnd...\1",pkmnname,oldmovename),&block)
pbMessage(_INTL("\\se[]{1} learned {2}!\\se[Pkmn move learnt]",pkmnname,movename),&block)
pkmn.changeHappiness("machine") if bymachine
return true
elsif pbConfirmMessage(_INTL("Give up on learning {1}?",movename),&block)
pbMessage(_INTL("{1} did not learn {2}.",pkmnname,movename),&block)
return false
end
end
end
def pbForgetMove(pkmn,moveToLearn)
ret = -1
pbFadeOutIn {
scene = PokemonSummary_Scene.new
screen = PokemonSummaryScreen.new(scene)
ret = screen.pbStartForgetScreen([pkmn],0,moveToLearn)
}
return ret
end
def pbSpeciesCompatible?(species,move)
return false if species<=0
data = pbLoadSpeciesTMData
return false if !data[move]
return data[move].any? { |item| item==species }
end
#===============================================================================
# Use an item from the Bag and/or on a Pokémon
#===============================================================================
def pbUseItem(bag,item,bagscene=nil)
found = false
useType = pbGetItemData(item,ITEM_FIELD_USE)
if pbIsMachine?(item) # TM or HM
if $Trainer.pokemonCount==0
pbMessage(_INTL("There is no Pokémon."))
return 0
end
machine = pbGetMachine(item)
return 0 if machine==nil
movename = PBMoves.getName(machine)
pbMessage(_INTL("\\se[PC access]You booted up {1}.\1",PBItems.getName(item)))
if !pbConfirmMessage(_INTL("Do you want to teach {1} to a Pokémon?",movename))
return 0
elsif pbMoveTutorChoose(machine,nil,true)
bag.pbDeleteItem(item) if pbIsTechnicalMachine?(item) && !INFINITE_TMS
return 1
end
return 0
elsif useType && (useType==1 || useType==5) # Item is usable on a Pokémon
if $Trainer.pokemonCount==0
pbMessage(_INTL("There is no Pokémon."))
return 0
end
ret = false
annot = nil
if pbIsEvolutionStone?(item)
annot = []
for pkmn in $Trainer.party
elig = pbCheckEvolution(pkmn,item)>0
annot.push((elig) ? _INTL("ABLE") : _INTL("NOT ABLE"))
end
end
pbFadeOutIn {
scene = PokemonParty_Scene.new
screen = PokemonPartyScreen.new(scene,$Trainer.party)
screen.pbStartScene(_INTL("Use on which Pokémon?"),false,annot)
loop do
scene.pbSetHelpText(_INTL("Use on which Pokémon?"))
chosen = screen.pbChoosePokemon
if chosen<0
ret = false
break
end
pkmn = $Trainer.party[chosen]
if pbCheckUseOnPokemon(item,pkmn,screen)
ret = ItemHandlers.triggerUseOnPokemon(item,pkmn,screen)
if ret && useType==1 # Usable on Pokémon, consumed
bag.pbDeleteItem(item)
if !bag.pbHasItem?(item)
pbMessage(_INTL("You used your last {1}.",PBItems.getName(item)))
break
end
end
end
end
screen.pbEndScene
bagscene.pbRefresh if bagscene
}
return (ret) ? 1 : 0
elsif useType && useType==2 # Item is usable from bag
intret = ItemHandlers.triggerUseFromBag(item)
case intret
when 0; return 0
when 1; return 1 # Item used
when 2; return 2 # Item used, end screen
when 3; bag.pbDeleteItem(item); return 1 # Item used, consume item
when 4; bag.pbDeleteItem(item); return 2 # Item used, end screen and consume item
end
pbMessage(_INTL("Can't use that here."))
return 0
end
pbMessage(_INTL("Can't use that here."))
return 0
end
# Only called when in the party screen and having chosen an item to be used on
# the selected Pokémon
def pbUseItemOnPokemon(item,pkmn,scene)
# TM or HM
if pbIsMachine?(item)
machine = pbGetMachine(item)
return false if machine==nil
movename = PBMoves.getName(machine)
if pkmn.shadowPokemon?
pbMessage(_INTL("Shadow Pokémon can't be taught any moves."))
elsif !pkmn.compatibleWithMove?(machine)
pbMessage(_INTL("{1} can't learn {2}.",pkmn.name,movename))
else
pbMessage(_INTL("\\se[PC access]You booted up {1}.\1",PBItems.getName(item)))
if pbConfirmMessage(_INTL("Do you want to teach {1} to {2}?",movename,pkmn.name))
if pbLearnMove(pkmn,machine,false,true)
$PokemonBag.pbDeleteItem(item) if pbIsTechnicalMachine?(item) && !INFINITE_TMS
return true
end
end
end
return false
end
# Other item
ret = ItemHandlers.triggerUseOnPokemon(item,pkmn,scene)
scene.pbClearAnnotations
scene.pbHardRefresh
useType = pbGetItemData(item,ITEM_FIELD_USE)
if ret && useType && useType==1 # Usable on Pokémon, consumed
$PokemonBag.pbDeleteItem(item)
if !$PokemonBag.pbHasItem?(item)
pbMessage(_INTL("You used your last {1}.",PBItems.getName(item)))
end
end
return ret
end
def pbUseKeyItemInField(item)
ret = ItemHandlers.triggerUseInField(item)
if ret==-1 # Item effect not found
pbMessage(_INTL("Can't use that here."))
elsif ret==3 # Item was used and consumed
$PokemonBag.pbDeleteItem(item)
end
return ret!=-1 && ret!=0
end
def pbUseItemMessage(item)
itemname = PBItems.getName(item)
if itemname.starts_with_vowel?
pbMessage(_INTL("You used an {1}.",itemname))
else
pbMessage(_INTL("You used a {1}.",itemname))
end
end
def pbCheckUseOnPokemon(item,pkmn,screen)
return pkmn && !pkmn.egg?
end
#===============================================================================
# Give an item to a Pokémon to hold, and take a held item from a Pokémon
#===============================================================================
def pbGiveItemToPokemon(item,pkmn,scene,pkmnid=0)
newitemname = PBItems.getName(item)
if pkmn.egg?
scene.pbDisplay(_INTL("Eggs can't hold items."))
return false
elsif pkmn.mail
scene.pbDisplay(_INTL("{1}'s mail must be removed before giving it an item.",pkmn.name))
return false if !pbTakeItemFromPokemon(pkmn,scene)
end
if pkmn.hasItem?
olditemname = PBItems.getName(pkmn.item)
if isConst?(pkmn.item,PBItems,:LEFTOVERS)
scene.pbDisplay(_INTL("{1} is already holding some {2}.\1",pkmn.name,olditemname))
elsif newitemname.starts_with_vowel?
scene.pbDisplay(_INTL("{1} is already holding an {2}.\1",pkmn.name,olditemname))
else
scene.pbDisplay(_INTL("{1} is already holding a {2}.\1",pkmn.name,olditemname))
end
if scene.pbConfirm(_INTL("Would you like to switch the two items?"))
$PokemonBag.pbDeleteItem(item)
if !$PokemonBag.pbStoreItem(pkmn.item)
if !$PokemonBag.pbStoreItem(item)
raise _INTL("Could't re-store deleted item in Bag somehow")
end
scene.pbDisplay(_INTL("The Bag is full. The Pokémon's item could not be removed."))
else
if pbIsMail?(item)
if pbWriteMail(item,pkmn,pkmnid,scene)
pkmn.setItem(item)
scene.pbDisplay(_INTL("Took the {1} from {2} and gave it the {3}.",olditemname,pkmn.name,newitemname))
return true
else
if !$PokemonBag.pbStoreItem(item)
raise _INTL("Couldn't re-store deleted item in Bag somehow")
end
end
else
pkmn.setItem(item)
scene.pbDisplay(_INTL("Took the {1} from {2} and gave it the {3}.",olditemname,pkmn.name,newitemname))
return true
end
end
end
else
if !pbIsMail?(item) || pbWriteMail(item,pkmn,pkmnid,scene)
$PokemonBag.pbDeleteItem(item)
pkmn.setItem(item)
scene.pbDisplay(_INTL("{1} is now holding the {2}.",pkmn.name,newitemname))
return true
end
end
return false
end
def pbTakeItemFromPokemon(pkmn,scene)
ret = false
if !pkmn.hasItem?
scene.pbDisplay(_INTL("{1} isn't holding anything.",pkmn.name))
elsif !$PokemonBag.pbCanStore?(pkmn.item)
scene.pbDisplay(_INTL("The Bag is full. The Pokémon's item could not be removed."))
elsif pkmn.mail
if scene.pbConfirm(_INTL("Save the removed mail in your PC?"))
if !pbMoveToMailbox(pkmn)
scene.pbDisplay(_INTL("Your PC's Mailbox is full."))
else
scene.pbDisplay(_INTL("The mail was saved in your PC."))
pkmn.setItem(0)
ret = true
end
elsif scene.pbConfirm(_INTL("If the mail is removed, its message will be lost. OK?"))
$PokemonBag.pbStoreItem(pkmn.item)
itemname = PBItems.getName(pkmn.item)
scene.pbDisplay(_INTL("Received the {1} from {2}.",itemname,pkmn.name))
pkmn.setItem(0)
pkmn.mail = nil
ret = true
end
else
$PokemonBag.pbStoreItem(pkmn.item)
itemname = PBItems.getName(pkmn.item)
scene.pbDisplay(_INTL("Received the {1} from {2}.",itemname,pkmn.name))
pkmn.setItem(0)
ret = true
end
return ret
end
#===============================================================================
# Choose an item from the Bag
#===============================================================================
def pbChooseItem(var=0,*args)
ret = 0
pbFadeOutIn {
scene = PokemonBag_Scene.new
screen = PokemonBagScreen.new(scene,$PokemonBag)
ret = screen.pbChooseItemScreen
}
$game_variables[var] = ret if var>0
return ret
end
def pbChooseApricorn(var=0)
ret = 0
pbFadeOutIn {
scene = PokemonBag_Scene.new
screen = PokemonBagScreen.new(scene,$PokemonBag)
ret = screen.pbChooseItemScreen(Proc.new { |item| pbIsApricorn?(item) })
}
$game_variables[var] = ret if var>0
return ret
end
def pbChooseFossil(var=0)
ret = 0
pbFadeOutIn {
scene = PokemonBag_Scene.new
screen = PokemonBagScreen.new(scene,$PokemonBag)
ret = screen.pbChooseItemScreen(Proc.new { |item| pbIsFossil?(item) })
}
$game_variables[var] = ret if var>0
return ret
end
# Shows a list of items to choose from, with the chosen item's ID being stored
# in the given Global Variable. Only items which the player has are listed.
def pbChooseItemFromList(message,variable,*args)
commands = []
itemid = []
for item in args
next if !hasConst?(PBItems,item)
id = getConst(PBItems,item)
next if !$PokemonBag.pbHasItem?(id)
commands.push(PBItems.getName(id))
itemid.push(id)
end
if commands.length==0
$game_variables[variable] = 0
return 0
end
commands.push(_INTL("Cancel"))
itemid.push(0)
ret = pbMessage(message,commands,-1)
if ret<0 || ret>=commands.length-1
$game_variables[variable] = -1
return -1
end
$game_variables[variable] = itemid[ret]
return itemid[ret]
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,677 @@
#===============================================================================
# CanUseInBattle handlers
#===============================================================================
ItemHandlers::CanUseInBattle.add(:GUARDSPEC,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !battler || battler.pbOwnSide.effects[PBEffects::Mist]>0
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.add(:POKEDOLL,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !battle.wildBattle?
if showMessages
scene.pbDisplay(_INTL("Oak's words echoed... There's a time and place for everything! But not now."))
end
next false
end
next true
})
ItemHandlers::CanUseInBattle.copy(:POKEDOLL,:FLUFFYTAIL,:POKETOY)
ItemHandlers::CanUseInBattle.addIf(proc { |item| pbIsPokeBall?(item) }, # Poké Balls
proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if battle.pbPlayer.party.length>=6 && $PokemonStorage.full?
scene.pbDisplay(_INTL("There is no room left in the PC!")) if showMessages
next false
end
# NOTE: Using a Poké Ball consumes all your actions for the round. The code
# below is one half of making this happen; the other half is in def
# pbItemUsesAllActions?.
if !firstAction
scene.pbDisplay(_INTL("It's impossible to aim without being focused!")) if showMessages
next false
end
if battler.semiInvulnerable?
scene.pbDisplay(_INTL("It's no good! It's impossible to aim at a Pokémon that's not in sight!")) if showMessages
next false
end
# NOTE: The code below stops you from throwing a Poké Ball if there is more
# than one unfainted opposing Pokémon. (Snag Balls can be thrown in
# this case, but only in trainer battles, and the trainer will deflect
# them if they are trying to catch a non-Shadow Pokémon.)
if battle.pbOpposingBattlerCount>1 && !(pbIsSnagBall?(item) && battle.trainerBattle?)
if battle.pbOpposingBattlerCount==2
scene.pbDisplay(_INTL("It's no good! It's impossible to aim when there are two Pokémon!")) if showMessages
else
scene.pbDisplay(_INTL("It's no good! It's impossible to aim when there are more than one Pokémon!")) if showMessages
end
next false
end
next true
}
)
ItemHandlers::CanUseInBattle.add(:POTION,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !pokemon.able? || pokemon.hp==pokemon.totalhp
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.copy(:POTION,
:SUPERPOTION,:HYPERPOTION,:MAXPOTION,:BERRYJUICE,:SWEETHEART,:FRESHWATER,
:SODAPOP,:LEMONADE,:MOOMOOMILK,:ORANBERRY,:SITRUSBERRY,:ENERGYPOWDER,
:ENERGYROOT)
ItemHandlers::CanUseInBattle.copy(:POTION,:RAGECANDYBAR) if !NEWEST_BATTLE_MECHANICS
ItemHandlers::CanUseInBattle.add(:AWAKENING,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanCureStatus?(PBStatuses::SLEEP,pokemon,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:AWAKENING,:CHESTOBERRY)
ItemHandlers::CanUseInBattle.add(:BLUEFLUTE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if battler && battler.hasActiveAbility?(:SOUNDPROOF)
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next pbBattleItemCanCureStatus?(PBStatuses::SLEEP,pokemon,scene,showMessages)
})
ItemHandlers::CanUseInBattle.add(:ANTIDOTE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanCureStatus?(PBStatuses::POISON,pokemon,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:ANTIDOTE,:PECHABERRY)
ItemHandlers::CanUseInBattle.add(:BURNHEAL,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanCureStatus?(PBStatuses::BURN,pokemon,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:BURNHEAL,:RAWSTBERRY)
ItemHandlers::CanUseInBattle.add(:PARALYZEHEAL,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanCureStatus?(PBStatuses::PARALYSIS,pokemon,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:PARALYZEHEAL,:PARLYZHEAL,:CHERIBERRY)
ItemHandlers::CanUseInBattle.add(:ICEHEAL,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanCureStatus?(PBStatuses::FROZEN,pokemon,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:ICEHEAL,:ASPEARBERRY)
ItemHandlers::CanUseInBattle.add(:FULLHEAL,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !pokemon.able? ||
(pokemon.status==PBStatuses::NONE &&
(!battler || battler.effects[PBEffects::Confusion]==0))
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.copy(:FULLHEAL,
:LAVACOOKIE,:OLDGATEAU,:CASTELIACONE,:LUMIOSEGALETTE,:SHALOURSABLE,
:BIGMALASADA,:LUMBERRY,:HEALPOWDER)
ItemHandlers::CanUseInBattle.copy(:FULLHEAL,:RAGECANDYBAR) if NEWEST_BATTLE_MECHANICS
ItemHandlers::CanUseInBattle.add(:FULLRESTORE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !pokemon.able? ||
(pokemon.hp==pokemon.totalhp && pokemon.status==PBStatuses::NONE &&
(!battler || battler.effects[PBEffects::Confusion]==0))
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.add(:REVIVE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if pokemon.able? || pokemon.egg?
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.copy(:REVIVE,:MAXREVIVE,:REVIVALHERB)
ItemHandlers::CanUseInBattle.add(:ETHER,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !pokemon.able? || move<0 ||
pokemon.moves[move].totalpp<=0 ||
pokemon.moves[move].pp==pokemon.moves[move].totalpp
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.copy(:ETHER,:MAXETHER,:LEPPABERRY)
ItemHandlers::CanUseInBattle.add(:ELIXIR,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !pokemon.able?
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
canRestore = false
for m in pokemon.moves
next if m.id==0
next if m.totalpp<=0 || m.pp==m.totalpp
canRestore = true
break
end
if !canRestore
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.copy(:ELIXIR,:MAXELIXIR)
ItemHandlers::CanUseInBattle.add(:REDFLUTE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !battler || battler.effects[PBEffects::Attract]<0 ||
battler.hasActiveAbility?(:SOUNDPROOF)
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.add(:PERSIMBERRY,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !battler || battler.effects[PBEffects::Confusion]==0
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.add(:YELLOWFLUTE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !battler || battler.effects[PBEffects::Confusion]==0 ||
battler.hasActiveAbility?(:SOUNDPROOF)
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.add(:XATTACK,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanRaiseStat?(PBStats::ATTACK,battler,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:XATTACK,:XATTACK2,:XATTACK3,:XATTACK6)
ItemHandlers::CanUseInBattle.add(:XDEFENSE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanRaiseStat?(PBStats::DEFENSE,battler,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:XDEFENSE,
:XDEFENSE2,:XDEFENSE3,:XDEFENSE6,:XDEFEND,:XDEFEND2,:XDEFEND3,:XDEFEND6)
ItemHandlers::CanUseInBattle.add(:XSPATK,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanRaiseStat?(PBStats::SPATK,battler,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:XSPATK,
:XSPATK2,:XSPATK3,:XSPATK6,:XSPECIAL,:XSPECIAL2,:XSPECIAL3,:XSPECIAL6)
ItemHandlers::CanUseInBattle.add(:XSPDEF,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanRaiseStat?(PBStats::SPDEF,battler,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:XSPDEF,:XSPDEF2,:XSPDEF3,:XSPDEF6)
ItemHandlers::CanUseInBattle.add(:XSPEED,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanRaiseStat?(PBStats::SPEED,battler,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:XSPEED,:XSPEED2,:XSPEED3,:XSPEED6)
ItemHandlers::CanUseInBattle.add(:XACCURACY,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanRaiseStat?(PBStats::ACCURACY,battler,scene,showMessages)
})
ItemHandlers::CanUseInBattle.copy(:XACCURACY,:XACCURACY2,:XACCURACY3,:XACCURACY6)
ItemHandlers::CanUseInBattle.add(:DIREHIT,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !battler || battler.effects[PBEffects::FocusEnergy]>=1
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.add(:DIREHIT2,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !battler || battler.effects[PBEffects::FocusEnergy]>=2
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.add(:DIREHIT3,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !battler || battler.effects[PBEffects::FocusEnergy]>=3
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.add(:POKEFLUTE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
anyAsleep = false
battle.eachBattler do |b|
next if b.status!=PBStatuses::SLEEP || b.hasActiveAbility?(:SOUNDPROOF)
anyAsleep = true
break
end
if !anyAsleep
scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages
next false
end
next true
})
#===============================================================================
# UseInBattle handlers
# For items used directly or on an opposing battler
#===============================================================================
ItemHandlers::UseInBattle.add(:GUARDSPEC,proc { |item,battler,battle|
battler.pbOwnSide.effects[PBEffects::Mist] = 5
battle.pbDisplay(_INTL("{1} became shrouded in mist!",battler.pbTeam))
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::UseInBattle.add(:POKEDOLL,proc { |item,battler,battle|
battle.decision = 3
battle.pbDisplayPaused(_INTL("You got away safely!"))
})
ItemHandlers::UseInBattle.copy(:POKEDOLL,:FLUFFYTAIL,:POKETOY)
ItemHandlers::UseInBattle.add(:POKEFLUTE,proc { |item,battler,battle|
battle.eachBattler do |b|
next if b.status!=PBStatuses::SLEEP || b.hasActiveAbility?(:SOUNDPROOF)
b.pbCureStatus(false)
end
scene.pbRefresh
scene.pbDisplay(_INTL("All Pokémon were roused by the tune!"))
})
ItemHandlers::UseInBattle.addIf(proc { |item| pbIsPokeBall?(item) }, # Poké Balls
proc { |item,battler,battle|
battle.pbThrowPokeBall(battler.index,item)
}
)
#===============================================================================
# BattleUseOnPokemon handlers
# For items used on Pokémon or on a Pokémon's move
#===============================================================================
ItemHandlers::BattleUseOnPokemon.add(:POTION,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,20,scene)
})
ItemHandlers::BattleUseOnPokemon.copy(:POTION,:BERRYJUICE,:SWEETHEART)
ItemHandlers::BattleUseOnPokemon.copy(:POTION,:RAGECANDYBAR) if !NEWEST_BATTLE_MECHANICS
ItemHandlers::BattleUseOnPokemon.add(:SUPERPOTION,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,50,scene)
})
ItemHandlers::BattleUseOnPokemon.add(:HYPERPOTION,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,200,scene)
})
ItemHandlers::BattleUseOnPokemon.add(:MAXPOTION,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,pokemon.totalhp-pokemon.hp,scene)
})
ItemHandlers::BattleUseOnPokemon.add(:FRESHWATER,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,50,scene)
})
ItemHandlers::BattleUseOnPokemon.add(:SODAPOP,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,60,scene)
})
ItemHandlers::BattleUseOnPokemon.add(:LEMONADE,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,80,scene)
})
ItemHandlers::BattleUseOnPokemon.add(:MOOMOOMILK,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,100,scene)
})
ItemHandlers::BattleUseOnPokemon.add(:ORANBERRY,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,10,scene)
})
ItemHandlers::BattleUseOnPokemon.add(:SITRUSBERRY,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,pokemon.totalhp/4,scene)
})
ItemHandlers::BattleUseOnPokemon.add(:AWAKENING,proc { |item,pokemon,battler,choices,scene|
pokemon.healStatus
battler.pbCureStatus(false) if battler
name = (battler) ? battler.pbThis : pokemon.name
scene.pbRefresh
scene.pbDisplay(_INTL("{1} woke up.",name))
})
ItemHandlers::BattleUseOnPokemon.copy(:AWAKENING,:CHESTOBERRY,:BLUEFLUTE)
ItemHandlers::BattleUseOnPokemon.add(:ANTIDOTE,proc { |item,pokemon,battler,choices,scene|
pokemon.healStatus
battler.pbCureStatus(false) if battler
name = (battler) ? battler.pbThis : pokemon.name
scene.pbRefresh
scene.pbDisplay(_INTL("{1} was cured of its poisoning.",name))
})
ItemHandlers::BattleUseOnPokemon.copy(:ANTIDOTE,:PECHABERRY)
ItemHandlers::BattleUseOnPokemon.add(:BURNHEAL,proc { |item,pokemon,battler,choices,scene|
pokemon.healStatus
battler.pbCureStatus(false) if battler
name = (battler) ? battler.pbThis : pokemon.name
scene.pbRefresh
scene.pbDisplay(_INTL("{1}'s burn was healed.",name))
})
ItemHandlers::BattleUseOnPokemon.copy(:BURNHEAL,:RAWSTBERRY)
ItemHandlers::BattleUseOnPokemon.add(:PARALYZEHEAL,proc { |item,pokemon,battler,choices,scene|
pokemon.healStatus
battler.pbCureStatus(false) if battler
name = (battler) ? battler.pbThis : pokemon.name
scene.pbRefresh
scene.pbDisplay(_INTL("{1} was cured of paralysis.",name))
})
ItemHandlers::BattleUseOnPokemon.copy(:PARALYZEHEAL,:PARLYZHEAL,:CHERIBERRY)
ItemHandlers::BattleUseOnPokemon.add(:ICEHEAL,proc { |item,pokemon,battler,choices,scene|
pokemon.healStatus
battler.pbCureStatus(false) if battler
name = (battler) ? battler.pbThis : pokemon.name
scene.pbRefresh
scene.pbDisplay(_INTL("{1} was thawed out.",name))
})
ItemHandlers::BattleUseOnPokemon.copy(:ICEHEAL,:ASPEARBERRY)
ItemHandlers::BattleUseOnPokemon.add(:FULLHEAL,proc { |item,pokemon,battler,choices,scene|
pokemon.healStatus
battler.pbCureStatus(false) if battler
battler.pbCureConfusion if battler
name = (battler) ? battler.pbThis : pokemon.name
scene.pbRefresh
scene.pbDisplay(_INTL("{1} became healthy.",name))
})
ItemHandlers::BattleUseOnPokemon.copy(:FULLHEAL,
:LAVACOOKIE,:OLDGATEAU,:CASTELIACONE,:LUMIOSEGALETTE,:SHALOURSABLE,
:BIGMALASADA,:LUMBERRY)
ItemHandlers::BattleUseOnPokemon.copy(:FULLHEAL,:RAGECANDYBAR) if NEWEST_BATTLE_MECHANICS
ItemHandlers::BattleUseOnPokemon.add(:FULLRESTORE,proc { |item,pokemon,battler,choices,scene|
pokemon.healStatus
battler.pbCureStatus(false) if battler
battler.pbCureConfusion if battler
name = (battler) ? battler.pbThis : pokemon.name
if pokemon.hp<pokemon.totalhp
pbBattleHPItem(pokemon,battler,pokemon.totalhp,scene)
else
scene.pbRefresh
scene.pbDisplay(_INTL("{1} became healthy.",name))
end
})
ItemHandlers::BattleUseOnPokemon.add(:REVIVE,proc { |item,pokemon,battler,choices,scene|
pokemon.hp = pokemon.totalhp/2
pokemon.hp = 1 if pokemon.hp<=0
pokemon.healStatus
scene.pbRefresh
scene.pbDisplay(_INTL("{1} recovered from fainting!",pokemon.name))
})
ItemHandlers::BattleUseOnPokemon.add(:MAXREVIVE,proc { |item,pokemon,battler,choices,scene|
pokemon.healHP
pokemon.healStatus
scene.pbRefresh
scene.pbDisplay(_INTL("{1} recovered from fainting!",pokemon.name))
})
ItemHandlers::BattleUseOnPokemon.add(:ENERGYPOWDER,proc { |item,pokemon,battler,choices,scene|
if pbBattleHPItem(pokemon,battler,50,scene)
pokemon.changeHappiness("powder")
end
})
ItemHandlers::BattleUseOnPokemon.add(:ENERGYROOT,proc { |item,pokemon,battler,choices,scene|
if pbBattleHPItem(pokemon,battler,200,scene)
pokemon.changeHappiness("energyroot")
end
})
ItemHandlers::BattleUseOnPokemon.add(:HEALPOWDER,proc { |item,pokemon,battler,choices,scene|
pokemon.healStatus
battler.pbCureStatus(false) if battler
battler.pbCureConfusion if battler
pokemon.changeHappiness("powder")
name = (battler) ? battler.pbThis : pokemon.name
scene.pbRefresh
scene.pbDisplay(_INTL("{1} became healthy.",name))
})
ItemHandlers::BattleUseOnPokemon.add(:REVIVALHERB,proc { |item,pokemon,battler,choices,scene|
pokemon.healHP
pokemon.healStatus
pokemon.changeHappiness("revivalherb")
scene.pbRefresh
scene.pbDisplay(_INTL("{1} recovered from fainting!",pokemon.name))
})
ItemHandlers::BattleUseOnPokemon.add(:ETHER,proc { |item,pokemon,battler,choices,scene|
idxMove = choices[3]
pbBattleRestorePP(pokemon,battler,idxMove,10)
scene.pbDisplay(_INTL("PP was restored."))
})
ItemHandlers::BattleUseOnPokemon.copy(:ETHER,:LEPPABERRY)
ItemHandlers::BattleUseOnPokemon.add(:MAXETHER,proc { |item,pokemon,battler,choices,scene|
idxMove = choices[3]
pbBattleRestorePP(pokemon,battler,idxMove,pokemon.moves[idxMove].totalpp)
scene.pbDisplay(_INTL("PP was restored."))
})
ItemHandlers::BattleUseOnPokemon.add(:ELIXIR,proc { |item,pokemon,battler,choices,scene|
for i in 0...pokemon.moves.length
pbBattleRestorePP(pokemon,battler,i,10)
end
scene.pbDisplay(_INTL("PP was restored."))
})
ItemHandlers::BattleUseOnPokemon.add(:MAXELIXIR,proc { |item,pokemon,battler,choices,scene|
for i in 0...pokemon.moves.length
pbBattleRestorePP(pokemon,battler,i,pokemon.moves[i].totalpp)
end
scene.pbDisplay(_INTL("PP was restored."))
})
#===============================================================================
# BattleUseOnBattler handlers
# For items used on a Pokémon in battle
#===============================================================================
ItemHandlers::BattleUseOnBattler.add(:REDFLUTE,proc { |item,battler,scene|
battler.pbCureAttract
scene.pbDisplay(_INTL("{1} got over its infatuation.",battler.pbThis))
})
ItemHandlers::BattleUseOnBattler.add(:YELLOWFLUTE,proc { |item,battler,scene|
battler.pbCureConfusion
scene.pbDisplay(_INTL("{1} snapped out of its confusion.",battler.pbThis))
})
ItemHandlers::BattleUseOnBattler.copy(:YELLOWFLUTE,:PERSIMBERRY)
ItemHandlers::BattleUseOnBattler.add(:XATTACK,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::ATTACK,(NEWEST_BATTLE_MECHANICS) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XATTACK2,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::ATTACK,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XATTACK3,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::ATTACK,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XATTACK6,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::ATTACK,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XDEFENSE,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::DEFENSE,(NEWEST_BATTLE_MECHANICS) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XDEFENSE,:XDEFEND)
ItemHandlers::BattleUseOnBattler.add(:XDEFENSE2,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::DEFENSE,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XDEFENSE2,:XDEFEND2)
ItemHandlers::BattleUseOnBattler.add(:XDEFENSE3,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::DEFENSE,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XDEFENSE3,:XDEFEND3)
ItemHandlers::BattleUseOnBattler.add(:XDEFENSE6,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::DEFENSE,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XDEFENSE6,:XDEFEND6)
ItemHandlers::BattleUseOnBattler.add(:XSPATK,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPATK,(NEWEST_BATTLE_MECHANICS) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XSPATK,:XSPECIAL)
ItemHandlers::BattleUseOnBattler.add(:XSPATK2,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPATK,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XSPATK2,:XSPECIAL2)
ItemHandlers::BattleUseOnBattler.add(:XSPATK3,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPATK,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XSPATK3,:XSPECIAL3)
ItemHandlers::BattleUseOnBattler.add(:XSPATK6,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPATK,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XSPATK6,:XSPECIAL6)
ItemHandlers::BattleUseOnBattler.add(:XSPDEF,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPDEF,(NEWEST_BATTLE_MECHANICS) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPDEF2,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPDEF,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPDEF3,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPDEF,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPDEF6,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPDEF,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPEED,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPEED,(NEWEST_BATTLE_MECHANICS) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPEED2,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPEED,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPEED3,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPEED,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPEED6,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::SPEED,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XACCURACY,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::ACCURACY,(NEWEST_BATTLE_MECHANICS) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XACCURACY2,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::ACCURACY,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XACCURACY3,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::ACCURACY,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XACCURACY6,proc { |item,battler,scene|
battler.pbRaiseStatStage(PBStats::ACCURACY,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:DIREHIT,proc { |item,battler,scene|
battler.effects[PBEffects::FocusEnergy] = 2
scene.pbDisplay(_INTL("{1} is getting pumped!",battler.pbThis))
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:DIREHIT2,proc { |item,battler,scene|
battler.effects[PBEffects::FocusEnergy] = 2
scene.pbDisplay(_INTL("{1} is getting pumped!",battler.pbThis))
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:DIREHIT3,proc { |item,battler,scene|
battler.effects[PBEffects::FocusEnergy] = 3
scene.pbDisplay(_INTL("{1} is getting pumped!",battler.pbThis))
battler.pokemon.changeHappiness("battleitem")
})

View File

@@ -0,0 +1,302 @@
#===============================================================================
# Register contacts
#===============================================================================
def pbPhoneRegisterNPC(ident,name,mapid,showmessage=true)
$PokemonGlobal.phoneNumbers = [] if !$PokemonGlobal.phoneNumbers
exists = pbFindPhoneTrainer(ident,name)
if exists
return if exists[0] # Already visible
exists[0] = true # Make visible
else
phonenum = [true,ident,name,mapid]
$PokemonGlobal.phoneNumbers.push(phonenum)
end
pbMessage(_INTL("\\me[Register phone]Registered {1} in the Pokégear.",name)) if showmessage
end
def pbPhoneRegister(event,trainertype,trainername)
$PokemonGlobal.phoneNumbers = [] if !$PokemonGlobal.phoneNumbers
return if pbFindPhoneTrainer(trainertype,trainername)
phonenum = []
phonenum.push(true)
phonenum.push(trainertype)
phonenum.push(trainername)
phonenum.push(0) # time to next battle
phonenum.push(0) # can battle
phonenum.push(0) # battle count
if event
phonenum.push(event.map.map_id)
phonenum.push(event.id)
end
$PokemonGlobal.phoneNumbers.push(phonenum)
end
def pbPhoneDeleteContact(index)
$PokemonGlobal.phoneNumbers[index][0] = false # Remove from contact list
if $PokemonGlobal.phoneNumbers[index].length==8
$PokemonGlobal.phoneNumbers[index][3] = 0 # Reset countdown
$PokemonGlobal.phoneNumbers[index][4] = 0 # Reset countdown
end
end
def pbPhoneRegisterBattle(message,event,trainertype,trainername,maxbattles)
return if !$Trainer.pokegear # Can't register without a Pokégear
if trainertype.is_a?(String) || trainertype.is_a?(Symbol)
return false if !hasConst?(PBTrainers,trainertype)
trainertype = PBTrainers.const_get(trainertype)
end
contact = pbFindPhoneTrainer(trainertype,trainername)
return if contact && contact[0] # Existing contact and is visible
message = _INTL("Let me register you.") if !message
return if !pbConfirmMessage(message)
displayname = _INTL("{1} {2}",PBTrainers.getName(trainertype),
pbGetMessageFromHash(MessageTypes::TrainerNames,trainername))
if contact # Previously registered, just make visible
contact[0] = true
else # Add new contact
pbPhoneRegister(event,trainertype,trainername)
pbPhoneIncrement(trainertype,trainername,maxbattles)
end
pbMessage(_INTL("\\me[Register phone]Registered {1} in the Pokégear.",displayname))
end
#===============================================================================
# Contact information
#===============================================================================
def pbRandomPhoneTrainer
$PokemonGlobal.phoneNumbers = [] if !$PokemonGlobal.phoneNumbers
temparray = []
currentRegion = pbGetMetadata($game_map.map_id,MetadataMapPosition)
for num in $PokemonGlobal.phoneNumbers
next if !num[0] || num.length!=8 # if not visible or not a trainer
next if $game_map.map_id==num[6] # Can't call if on same map
callerRegion = pbGetMetadata(num[6],MetadataMapPosition)
# Can't call if in different region
next if callerRegion && currentRegion && callerRegion[0]!=currentRegion[0]
temparray.push(num)
end
return nil if temparray.length==0
return temparray[rand(temparray.length)]
end
def pbFindPhoneTrainer(trtype,trname) # Ignores whether visible or not
return nil if !$PokemonGlobal.phoneNumbers
trtype = getID(PBTrainers,trtype)
return nil if !trtype || trtype<=0
for num in $PokemonGlobal.phoneNumbers
return num if num[1]==trtype && num[2]==trname # If a match
end
return nil
end
def pbHasPhoneTrainer?(trtype,trname)
return pbFindPhoneTrainer!=nil
end
def pbPhoneBattleCount(trtype,trname)
trainer = pbFindPhoneTrainer(trtype,trname)
return trainer[5] if trainer
return 0
end
def pbPhoneReadyToBattle?(trtype,trname)
trainer = pbFindPhoneTrainer(trtype,trname)
return (trainer && trainer[4]>=2)
end
#===============================================================================
# Contact rematch data modifications
#===============================================================================
def pbPhoneIncrement(trtype,trname,maxbattles)
trainer = pbFindPhoneTrainer(trtype,trname)
return if !trainer
trainer[5] += 1 if trainer[5]<maxbattles # Increment battle count
trainer[3] = 0 # reset time to can-battle
trainer[4] = 0 # reset can-battle flag
end
def pbPhoneReset(trtype,trname)
trainer = pbFindPhoneTrainer(trtype,trname)
return false if !trainer
trainer[3] = 0 # reset time to can-battle
trainer[4] = 0 # reset can-battle flag
return true
end
def pbSetReadyToBattle(num)
return if !num[6] || !num[7]
$game_self_switches[[num[6],num[7],"A"]] = false
$game_self_switches[[num[6],num[7],"B"]] = true
$game_map.need_refresh = true
end
#===============================================================================
# Phone-related counters
#===============================================================================
Events.onMapUpdate += proc { |sender,e|
next if !$Trainer || !$Trainer.pokegear
# Reset time to next phone call if necessary
if !$PokemonGlobal.phoneTime || $PokemonGlobal.phoneTime<=0
$PokemonGlobal.phoneTime = 20*60*Graphics.frame_rate
$PokemonGlobal.phoneTime += rand(20*60*Graphics.frame_rate)
end
# Don't count down various phone times if other things are happening
$PokemonGlobal.phoneNumbers = [] if !$PokemonGlobal.phoneNumbers
next if $game_temp.in_menu || $game_temp.in_battle || $game_temp.message_window_showing
next if $game_player.move_route_forcing || pbMapInterpreterRunning?
# Count down time to next phone call
$PokemonGlobal.phoneTime -= 1
# Count down time to next can-battle for each trainer contact
if $PokemonGlobal.phoneTime%Graphics.frame_rate==0 # Every second
for num in $PokemonGlobal.phoneNumbers
next if !num[0] || num.length!=8 # if not visible or not a trainer
# Reset time to next can-battle if necessary
if num[4]==0
num[3] = 20*60+rand(20*60) # 20-40 minutes
num[4] = 1
end
# Count down time to next can-battle
num[3] -= 1
# Ready to battle
if num[3]<=0 && num[4]==1
num[4] = 2 # set ready-to-battle flag
pbSetReadyToBattle(num)
end
end
end
# Time for a random phone call; generate one
if $PokemonGlobal.phoneTime<=0
# find all trainer phone numbers
phonenum = pbRandomPhoneTrainer
if phonenum
call = pbPhoneGenerateCall(phonenum)
pbPhoneCall(call,phonenum)
end
end
}
#===============================================================================
# Player calls a contact
#===============================================================================
def pbCallTrainer(trtype,trname)
trainer = pbFindPhoneTrainer(trtype,trname)
return if !trainer
# Special NPC contacts
if trainer.length!=8
if !pbCommonEvent(trtype)
pbMessage(_INTL("{1}'s messages not defined.\nCouldn't call common event {2}.",trainer[2],trtype))
end
return
end
# Trainer contacts
if $game_map.map_id==trainer[6]
pbMessage(_INTL("The Trainer is close by.\nTalk to the Trainer in person!"))
return
end
callerregion = pbGetMetadata(trainer[6],MetadataMapPosition)
currentregion = pbGetMetadata($game_map.map_id,MetadataMapPosition)
if callerregion && currentregion && callerregion[0]!=currentregion[0]
pbMessage(_INTL("The Trainer is out of range."))
return # Can't call if in different region
end
call = pbPhoneGenerateCall(trainer)
pbPhoneCall(call,trainer)
end
#===============================================================================
# Generate phone message
#===============================================================================
def pbPhoneGenerateCall(phonenum)
call = ""
phoneData = pbLoadPhoneData
# Choose random greeting depending on time of day
call = pbRandomPhoneItem(phoneData.greetings)
time = pbGetTimeNow
if PBDayNight.isMorning?(time)
modcall = pbRandomPhoneItem(phoneData.greetingsMorning)
call = modcall if modcall && modcall!=""
elsif PBDayNight.isEvening?(time)
modcall = pbRandomPhoneItem(phoneData.greetingsEvening)
call = modcall if modcall && modcall!=""
end
call += "\\m"
if phonenum[4]==2 || (rand(2)==0 && phonenum[4]==3)
# If "can battle" is set, make ready to battle
call += pbRandomPhoneItem(phoneData.battleRequests)
pbSetReadyToBattle(phonenum)
phonenum[4] = 3
elsif rand(4)<3
# Choose random body
call += pbRandomPhoneItem(phoneData.bodies1)
call += "\\m"
call += pbRandomPhoneItem(phoneData.bodies2)
else
# Choose random generic
call += pbRandomPhoneItem(phoneData.generics)
end
return call
end
def pbRandomPhoneItem(array)
ret = array[rand(array.length)]
ret = "" if !ret
return pbGetMessageFromHash(MessageTypes::PhoneMessages,ret)
end
def pbRandomEncounterSpecies(enctype)
return 0 if !enctype
len = [enctype.length,4].min
return enctype[rand(len)][0]
end
def pbEncounterSpecies(phonenum)
return "" if !phonenum[6] || phonenum[6]==0
begin
enctypes = $PokemonEncounters.pbGetEncounterTables(phonenum[6])
return "" if !enctypes
rescue
return ""
end
species = pbRandomEncounterSpecies(enctypes[EncounterTypes::Land])
species = pbRandomEncounterSpecies(enctypes[EncounterTypes::Cave]) if species==0
species = pbRandomEncounterSpecies(enctypes[EncounterTypes::LandDay]) if species==0
species = pbRandomEncounterSpecies(enctypes[EncounterTypes::LandMorning]) if species==0
species = pbRandomEncounterSpecies(enctypes[EncounterTypes::LandNight]) if species==0
species = pbRandomEncounterSpecies(enctypes[EncounterTypes::Water]) if species==0
return "" if species==0
return PBSpecies.getName(species)
end
def pbTrainerSpecies(phonenum)
return "" if !phonenum[0]
partyid = [0,(phonenum[5]-1)].max
trainer = pbGetTrainerData(phonenum[1],phonenum[2],partyid)
return "" if !trainer || trainer[3].length==0
rndpoke = trainer[3][rand(trainer[3].length)]
return PBSpecies.getName(rndpoke[0])
end
def pbTrainerMapName(phonenum)
return "" if !phonenum[6] || phonenum[6]==0
return pbGetMessage(MessageTypes::MapNames,phonenum[6])
end
#===============================================================================
# The phone call itself
#===============================================================================
def pbPhoneCall(call,phonenum)
pbMessage(_INTL("......\\wt[5] ......\\1"))
encspecies = pbEncounterSpecies(phonenum)
trainerspecies = pbTrainerSpecies(phonenum)
trainermap = pbTrainerMapName(phonenum)
messages = call.split("\\m")
for i in 0...messages.length
messages[i].gsub!(/\\TN/,phonenum[2])
messages[i].gsub!(/\\TP/,trainerspecies)
messages[i].gsub!(/\\TE/,encspecies)
messages[i].gsub!(/\\TM/,trainermap)
messages[i] += "\\1" if i<messages.length-1
pbMessage(messages[i])
end
pbMessage(_INTL("Click!\\wt[10]\n......\\wt[5] ......\\1"))
end

View File

@@ -0,0 +1,252 @@
class PokemonGlobalMetadata
attr_accessor :pokeradarBattery
end
class PokemonTemp
attr_accessor :pokeradar # [species, level, chain count, grasses (x,y,ring,rarity)]
end
################################################################################
# Using the Poke Radar
################################################################################
def pbCanUsePokeRadar?
# Can't use Radar if not in tall grass
if !PBTerrain.isJustGrass?($game_map.terrain_tag($game_player.x,$game_player.y))
pbMessage(_INTL("Can't use that here."))
return false
end
# Can't use Radar if map has no grass-based encounters (ignoring Bug Contest)
if !$PokemonEncounters.isRegularGrass?
pbMessage(_INTL("Can't use that here."))
return false
end
# Can't use Radar while cycling
if $PokemonGlobal.bicycle
pbMessage(_INTL("Can't use that while on a bicycle."))
return false
end
# Debug
return true if $DEBUG && Input.press?(Input::CTRL)
# Can't use Radar if it isn't fully charged
if $PokemonGlobal.pokeradarBattery && $PokemonGlobal.pokeradarBattery>0
pbMessage(_INTL("The battery has run dry!\nFor it to recharge, you need to walk another {1} steps.",
$PokemonGlobal.pokeradarBattery))
return false
end
return true
end
def pbUsePokeRadar
return false if !pbCanUsePokeRadar?
$PokemonTemp.pokeradar = [0,0,0,[]] if !$PokemonTemp.pokeradar
$PokemonGlobal.pokeradarBattery = 50
pbPokeRadarHighlightGrass
return true
end
def pbPokeRadarHighlightGrass(showmessage=true)
grasses = [] # x, y, ring (0-3 inner to outer), rarity
# Choose 1 random tile from each ring around the player
for i in 0...4
r = rand((i+1)*8)
# Get coordinates of randomly chosen tile
x = $game_player.x
y = $game_player.y
if r<=(i+1)*2
x = $game_player.x-i-1+r
y = $game_player.y-i-1
elsif r<=(i+1)*6-2
x = [$game_player.x+i+1,$game_player.x-i-1][r%2]
y = $game_player.y-i+((r-1-(i+1)*2)/2).floor
else
x = $game_player.x-i+r-(i+1)*6
y = $game_player.y+i+1
end
# Add tile to grasses array if it's a valid grass tile
if x>=0 && x<$game_map.width &&
y>=0 && y<$game_map.height
if PBTerrain.isJustGrass?($game_map.terrain_tag(x,y))
# Choose a rarity for the grass (0=normal, 1=rare, 2=shiny)
s = (rand(4)==0) ? 1 : 0
if $PokemonTemp.pokeradar && $PokemonTemp.pokeradar[2]>0
v = [(65536/SHINY_POKEMON_CHANCE)-$PokemonTemp.pokeradar[2]*200,200].max
v = 0xFFFF/v
v = rand(65536)/v
s = 2 if v==0
end
grasses.push([x,y,i,s])
end
end
end
if grasses.length==0
# No shaking grass found, break the chain
pbMessage(_INTL("The grassy patch remained quiet...")) if showmessage
pbPokeRadarCancel
else
# Show grass rustling animations
for grass in grasses
case grass[3]
when 0 # Normal rustle
$scene.spriteset.addUserAnimation(RUSTLE_NORMAL_ANIMATION_ID,grass[0],grass[1],true,1)
when 1 # Vigorous rustle
$scene.spriteset.addUserAnimation(RUSTLE_VIGOROUS_ANIMATION_ID,grass[0],grass[1],true,1)
when 2 # Shiny rustle
$scene.spriteset.addUserAnimation(RUSTLE_SHINY_ANIMATION_ID,grass[0],grass[1],true,1)
end
end
$PokemonTemp.pokeradar[3] = grasses if $PokemonTemp.pokeradar
pbWait(Graphics.frame_rate/2)
end
end
def pbPokeRadarCancel
$PokemonTemp.pokeradar = nil
end
def pbPokeRadarGetShakingGrass
return -1 if !$PokemonTemp.pokeradar
grasses = $PokemonTemp.pokeradar[3]
return -1 if grasses.length==0
for i in grasses
return i[2] if $game_player.x==i[0] && $game_player.y==i[1]
end
return -1
end
def pbPokeRadarOnShakingGrass
return pbPokeRadarGetShakingGrass>=0
end
def pbPokeRadarGetEncounter(rarity=0)
# Poké Radar-exclusive encounters can only be found in vigorously-shaking grass
if rarity>0
# Get all Poké Radar-exclusive encounters for this map
map = $game_map.map_id rescue 0
array = []
for enc in POKE_RADAR_ENCOUNTERS
array.push(enc) if enc.length>=4 && enc[0]==map && getID(PBSpecies,enc[2])>0
end
# If there are any exclusives, first have a chance of encountering those
if array.length>0
rnd = rand(100)
chance = 0
for enc in array
chance += enc[1]
if rnd<chance
upper = (enc[4]!=nil) ? enc[4] : enc[3]
level = enc[3]+rand(1+upper-enc[3])
return [getID(PBSpecies,enc[2]),level]
end
end
end
end
# Didn't choose a Poké Radar-exclusive species, choose a regular encounter instead
return $PokemonEncounters.pbEncounteredPokemon($PokemonEncounters.pbEncounterType,rarity+1)
end
################################################################################
# Event handlers
################################################################################
EncounterModifier.register(proc { |encounter|
next encounter if EncounterTypes::EnctypeCompileDens[$PokemonTemp.encounterType]!=1
if !$PokemonEncounters.isRegularGrass? ||
!$PokemonEncounters.isEncounterPossibleHere? ||
$PokemonGlobal.partner
pbPokeRadarCancel
next encounter
end
grass = pbPokeRadarGetShakingGrass
if grass>=0
# Get rarity of shaking grass
s = 0
for g in $PokemonTemp.pokeradar[3]
s = g[3] if g[2]==grass
end
if $PokemonTemp.pokeradar[2]>0
if s==2 || rand(100)<86+grass*4+($PokemonTemp.pokeradar[2]/4).floor
# Continue the chain
encounter = [$PokemonTemp.pokeradar[0],$PokemonTemp.pokeradar[1]]
$PokemonTemp.forceSingleBattle = true
else
# Break the chain, force an encounter with a different species
100.times do
break if encounter && encounter[0]!=$PokemonTemp.pokeradar[0]
encounter = $PokemonEncounters.pbEncounteredPokemon($PokemonEncounters.pbEncounterType)
end
pbPokeRadarCancel
end
else
# Force random wild encounter, vigorous shaking means rarer species
encounter = pbPokeRadarGetEncounter(s)
$PokemonTemp.forceSingleBattle = true
end
else
pbPokeRadarCancel if encounter # Encounter is not in shaking grass
end
next encounter
})
Events.onWildPokemonCreate += proc { |sender,e|
pokemon = e[0]
next if !$PokemonTemp.pokeradar
grasses = $PokemonTemp.pokeradar[3]
next if !grasses
for grass in grasses
next if $game_player.x!=grass[0] || $game_player.y!=grass[1]
pokemon.makeShiny if grass[3]==2
break
end
}
Events.onWildBattleEnd += proc { |sender,e|
species = e[0]
level = e[1]
decision = e[2]
if !$PokemonEncounters.isRegularGrass? || $PokemonGlobal.bicycle
pbPokeRadarCancel
next
end
if $PokemonTemp.pokeradar && (decision==1 || decision==4) # Defeated/caught
$PokemonTemp.pokeradar[0] = species
$PokemonTemp.pokeradar[1] = level
$PokemonTemp.pokeradar[2] += 1
$PokemonTemp.pokeradar[2] = 40 if $PokemonTemp.pokeradar[2]>40
pbPokeRadarHighlightGrass(false)
else
pbPokeRadarCancel
end
}
Events.onStepTaken += proc { |sender,e|
if $PokemonGlobal.pokeradarBattery && $PokemonGlobal.pokeradarBattery>0 &&
!$PokemonTemp.pokeradar
$PokemonGlobal.pokeradarBattery -= 1
end
if !$PokemonEncounters.isRegularGrass? ||
!PBTerrain.isJustGrass?($game_map.terrain_tag($game_player.x,$game_player.y))
pbPokeRadarCancel
end
}
Events.onMapUpdate += proc { |sender,e|
pbPokeRadarCancel if $PokemonGlobal.bicycle
}
Events.onMapChange += proc { |sender,e|
pbPokeRadarCancel
}
################################################################################
# Item handlers
################################################################################
ItemHandlers::UseInField.add(:POKERADAR,proc { |item|
next (pbCanUsePokeRadar?) ? pbUsePokeRadar : 0
})
ItemHandlers::UseFromBag.add(:POKERADAR,proc { |item|
next (pbCanUsePokeRadar?) ? 2 : 0
})

View File

@@ -0,0 +1,117 @@
# Data structure representing mail that the Pokémon can hold
class PokemonMail
attr_accessor :item,:message,:sender,:poke1,:poke2,:poke3
def initialize(item,message,sender,poke1=nil,poke2=nil,poke3=nil)
@item = item # Item represented by this mail
@message = message # Message text
@sender = sender # Name of the message's sender
@poke1 = poke1 # [species,gender,shininess,form,shadowness,is egg]
@poke2 = poke2
@poke3 = poke3
end
end
def pbMoveToMailbox(pokemon)
$PokemonGlobal.mailbox = [] if !$PokemonGlobal.mailbox
return false if $PokemonGlobal.mailbox.length>=10
return false if !pokemon.mail
$PokemonGlobal.mailbox.push(pokemon.mail)
pokemon.mail = nil
return true
end
def pbStoreMail(pkmn,item,message,poke1=nil,poke2=nil,poke3=nil)
raise _INTL("Pokémon already has mail") if pkmn.mail
pkmn.mail = PokemonMail.new(item,message,$Trainer.name,poke1,poke2,poke3)
end
def pbDisplayMail(mail,bearer=nil)
sprites = {}
viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
viewport.z = 99999
addBackgroundPlane(sprites,"background","mailbg",viewport)
sprites["card"] = IconSprite.new(0,0,viewport)
sprites["card"].setBitmap(pbMailBackFile(mail.item))
sprites["overlay"] = BitmapSprite.new(Graphics.width,Graphics.height,viewport)
overlay = sprites["overlay"].bitmap
pbSetSystemFont(overlay)
if pbIsMailWithPokemonIcons?(mail.item)
if mail.poke1
sprites["bearer"] = IconSprite.new(64,288,viewport)
bitmapFileName = pbCheckPokemonIconFiles(mail.poke1,mail.poke1[5])
sprites["bearer"].setBitmap(bitmapFileName)
sprites["bearer"].src_rect.set(0,0,64,64)
end
if mail.poke2
sprites["bearer2"] = IconSprite.new(144,288,viewport)
bitmapFileName = pbCheckPokemonIconFiles(mail.poke2,mail.poke2[5])
sprites["bearer2"].setBitmap(bitmapFileName)
sprites["bearer2"].src_rect.set(0,0,64,64)
end
if mail.poke3
sprites["bearer3"] = IconSprite.new(224,288,viewport)
bitmapFileName = pbCheckPokemonIconFiles(mail.poke3,mail.poke3[5])
sprites["bearer3"].setBitmap(bitmapFileName)
sprites["bearer3"].src_rect.set(0,0,64,64)
end
end
baseForDarkBG = Color.new(248,248,248)
shadowForDarkBG = Color.new(72,80,88)
baseForLightBG = Color.new(80,80,88)
shadowForLightBG = Color.new(168,168,176)
if mail.message && mail.message!=""
isDark = isDarkBackground(sprites["card"].bitmap,Rect.new(48,48,Graphics.width-96,32*7))
drawTextEx(overlay,48,48,Graphics.width-(48*2),7,mail.message,
(isDark) ? baseForDarkBG : baseForLightBG,
(isDark) ? shadowForDarkBG : shadowForLightBG)
end
if mail.sender && mail.sender!=""
isDark = isDarkBackground(sprites["card"].bitmap,Rect.new(336,322,144,32*1))
drawTextEx(overlay,336,322,144,1,mail.sender,
(isDark) ? baseForDarkBG : baseForLightBG,
(isDark) ? shadowForDarkBG : shadowForLightBG)
end
pbFadeInAndShow(sprites)
loop do
Graphics.update
Input.update
pbUpdateSpriteHash(sprites)
if Input.trigger?(Input::B) || Input.trigger?(Input::C)
break
end
end
pbFadeOutAndHide(sprites)
pbDisposeSpriteHash(sprites)
viewport.dispose
end
def pbWriteMail(item,pkmn,pkmnid,scene)
message = ""
loop do
message = pbMessageFreeText(_INTL("Please enter a message (max. 256 characters)."),
"",false,256,Graphics.width) { scene.pbUpdate }
if message!=""
# Store mail if a message was written
poke1 = poke2 = poke3 = nil
if $Trainer.party[pkmnid+2]
p = $Trainer.party[pkmnid+2]
poke1 = [p.species,p.gender,p.shiny?,(p.form rescue 0),p.shadowPokemon?]
poke1.push(true) if p.egg?
end
if $Trainer.party[pkmnid+1]
p = $Trainer.party[pkmnid+1]
poke2 = [p.species,p.gender,p.shiny?,(p.form rescue 0),p.shadowPokemon?]
poke2.push(true) if p.egg?
end
poke3 = [pkmn.species,pkmn.gender,pkmn.shiny?,(pkmn.form rescue 0),pkmn.shadowPokemon?]
poke3.push(true) if pkmn.egg?
pbStoreMail(pkmn,item,message,poke1,poke2,poke3)
return true
else
return false if scene.pbConfirm(_INTL("Stop giving the Pokémon Mail?"))
end
end
end

View File

@@ -0,0 +1,158 @@
#===============================================================================
# Item icon
#===============================================================================
class ItemIconSprite < SpriteWrapper
attr_reader :item
ANIM_ICON_SIZE = 48
FRAMES_PER_CYCLE = Graphics.frame_rate
def initialize(x,y,item,viewport=nil)
super(viewport)
@animbitmap = nil
@animframe = 0
@numframes = 1
@frame = 0
self.x = x
self.y = y
@forceitemchange = true
self.item = item
@forceitemchange = false
@blankzero = false
end
def dispose
@animbitmap.dispose if @animbitmap
super
end
def width
return 0 if !self.bitmap || self.bitmap.disposed?
return (@numframes==1) ? self.bitmap.width : ANIM_ICON_SIZE
end
def height
return (self.bitmap && !self.bitmap.disposed?) ? self.bitmap.height : 0
end
def blankzero=(val)
@blankzero = val
@forceitemchange = true
self.item = @item
@forceitemchange = false
end
def setOffset(offset=PictureOrigin::Center)
@offset = offset
changeOrigin
end
def changeOrigin
@offset = PictureOrigin::Center if !@offset
case @offset
when PictureOrigin::TopLeft, PictureOrigin::Top, PictureOrigin::TopRight
self.oy = 0
when PictureOrigin::Left, PictureOrigin::Center, PictureOrigin::Right
self.oy = self.height/2
when PictureOrigin::BottomLeft, PictureOrigin::Bottom, PictureOrigin::BottomRight
self.oy = self.height
end
case @offset
when PictureOrigin::TopLeft, PictureOrigin::Left, PictureOrigin::BottomLeft
self.ox = 0
when PictureOrigin::Top, PictureOrigin::Center, PictureOrigin::Bottom
self.ox = self.width/2
when PictureOrigin::TopRight, PictureOrigin::Right, PictureOrigin::BottomRight
self.ox = self.width
end
end
def item=(value)
return if @item==value && !@forceitemchange
@item = value
@animbitmap.dispose if @animbitmap
@animbitmap = nil
if @item && !(@item==0 && @blankzero)
@animbitmap = AnimatedBitmap.new(pbItemIconFile(value))
self.bitmap = @animbitmap.bitmap
if self.bitmap.height==ANIM_ICON_SIZE
@numframes = [(self.bitmap.width/ANIM_ICON_SIZE).floor,1].max
self.src_rect = Rect.new(0,0,ANIM_ICON_SIZE,ANIM_ICON_SIZE)
else
@numframes = 1
self.src_rect = Rect.new(0,0,self.bitmap.width,self.bitmap.height)
end
@animframe = 0
@frame = 0
else
self.bitmap = nil
end
changeOrigin
end
def update
@updating = true
super
if @animbitmap
@animbitmap.update
self.bitmap = @animbitmap.bitmap
if @numframes>1
frameskip = (FRAMES_PER_CYCLE/@numframes).floor
@frame = (@frame+1)%FRAMES_PER_CYCLE
if @frame>=frameskip
@animframe = (@animframe+1)%@numframes
self.src_rect.x = @animframe*ANIM_ICON_SIZE
@frame = 0
end
end
end
@updating = false
end
end
#===============================================================================
# Item held icon (used in the party screen)
#===============================================================================
class HeldItemIconSprite < SpriteWrapper
def initialize(x,y,pokemon,viewport=nil)
super(viewport)
self.x = x
self.y = y
@pokemon = pokemon
@item = 0
self.item = @pokemon.item
end
def pokemon=(value)
@pokemon = value
self.item = @pokemon.item
end
def item=(value)
return if @item==value
@item = value
@animbitmap.dispose if @animbitmap
@animbitmap = nil
if @item && @item>0
@animbitmap = AnimatedBitmap.new(pbHeldItemIconFile(value))
self.bitmap = @animbitmap.bitmap
else
self.bitmap = nil
end
end
def dispose
@animbitmap.dispose if @animbitmap
super
end
def update
super
self.item = @pokemon.item
if @animbitmap
@animbitmap.update
self.bitmap = @animbitmap.bitmap
end
end
end

View File

@@ -0,0 +1,401 @@
#===============================================================================
# The Bag object, which actually contains all the items
#===============================================================================
class PokemonBag
attr_accessor :lastpocket
attr_reader :pockets
def self.pocketNames
return pbPocketNames
end
def self.numPockets
return self.pocketNames.length-1
end
def initialize
@lastpocket = 1
@pockets = []
@choices = []
for i in 0..PokemonBag.numPockets
@pockets[i] = []
@choices[i] = 0
end
@registeredItems = []
@registeredIndex = [0,0,1]
end
def rearrange
if (@pockets.length-1)!=PokemonBag.numPockets
newpockets = []
for i in 0..PokemonBag.numPockets
newpockets[i] = []
@choices[i] = 0 if !@choices[i]
end
nump = PokemonBag.numPockets
for i in 0...[@pockets.length,nump].min
for item in @pockets[i]
p = pbGetPocket(item[0])
newpockets[p].push(item)
end
end
@pockets = newpockets
end
end
def clear
for pocket in @pockets
pocket.clear
end
end
def pockets
rearrange
return @pockets
end
def maxPocketSize(pocket)
maxsize = BAG_MAX_POCKET_SIZE[pocket]
return -1 if !maxsize
return maxsize
end
# Gets the index of the current selected item in the pocket
def getChoice(pocket)
if pocket<=0 || pocket>PokemonBag.numPockets
raise ArgumentError.new(_INTL("Invalid pocket: {1}",pocket.inspect))
end
rearrange
return [@choices[pocket],@pockets[pocket].length].min || 0
end
# Sets the index of the current selected item in the pocket
def setChoice(pocket,value)
if pocket<=0 || pocket>PokemonBag.numPockets
raise ArgumentError.new(_INTL("Invalid pocket: {1}",pocket.inspect))
end
rearrange
@choices[pocket] = value if value<=@pockets[pocket].length
end
def getAllChoices
ret = @choices.clone
for i in 0...@choices.length; @choices[i] = 0; end
return ret
end
def setAllChoices(choices)
@choices = choices
end
def pbQuantity(item)
item = getID(PBItems,item)
if !item || item<1
raise ArgumentError.new(_INTL("Item number {1} is invalid.",item))
return 0
end
pocket = pbGetPocket(item)
maxsize = maxPocketSize(pocket)
maxsize = @pockets[pocket].length if maxsize<0
return ItemStorageHelper.pbQuantity(@pockets[pocket],maxsize,item)
end
def pbHasItem?(item)
return pbQuantity(item)>0
end
def pbCanStore?(item,qty=1)
item = getID(PBItems,item)
if !item || item<1
raise ArgumentError.new(_INTL("Item number {1} is invalid.",item))
return false
end
pocket = pbGetPocket(item)
maxsize = maxPocketSize(pocket)
maxsize = @pockets[pocket].length+1 if maxsize<0
return ItemStorageHelper.pbCanStore?(@pockets[pocket],maxsize,
BAG_MAX_PER_SLOT,item,qty)
end
def pbStoreAllOrNone(item,qty=1)
item = getID(PBItems,item)
if !item || item<1
raise ArgumentError.new(_INTL("Item number {1} is invalid.",item))
return false
end
pocket = pbGetPocket(item)
maxsize = maxPocketSize(pocket)
maxsize = @pockets[pocket].length+1 if maxsize<0
return ItemStorageHelper.pbStoreAllOrNone(@pockets[pocket],maxsize,
BAG_MAX_PER_SLOT,item,qty)
end
def pbStoreItem(item,qty=1)
item = getID(PBItems,item)
if !item || item<1
raise ArgumentError.new(_INTL("Item number {1} is invalid.",item))
return false
end
pocket = pbGetPocket(item)
maxsize = maxPocketSize(pocket)
maxsize = @pockets[pocket].length+1 if maxsize<0
return ItemStorageHelper.pbStoreItem(@pockets[pocket],maxsize,
BAG_MAX_PER_SLOT,item,qty,true)
end
def pbChangeItem(olditem,newitem)
olditem = getID(PBItems,olditem)
newitem = getID(PBItems,newitem)
if !olditem || olditem<1
raise ArgumentError.new(_INTL("Item number {1} is invalid.",olditem))
return false
elsif !newitem || newitem<1
raise ArgumentError.new(_INTL("Item number {1} is invalid.",newitem))
return false
end
pocket = pbGetPocket(olditem)
maxsize = maxPocketSize(pocket)
maxsize = @pockets[pocket].length if maxsize<0
ret = false
for i in 0...maxsize
itemslot = @pockets[pocket][i]
if itemslot && itemslot[0]==olditem
itemslot[0] = newitem
ret = true
end
end
return ret
end
def pbChangeQuantity(pocket,index,newqty=1)
return false if pocket<=0 || pocket>self.numPockets
return false if @pockets[pocket].length<index
newqty = [newqty,maxPocketSize(pocket)].min
@pockets[pocket][index][1] = newqty
return true
end
def pbDeleteItem(item,qty=1)
item = getID(PBItems,item)
if !item || item<1
raise ArgumentError.new(_INTL("Item number {1} is invalid.",item))
return false
end
pocket = pbGetPocket(item)
maxsize = maxPocketSize(pocket)
maxsize = @pockets[pocket].length if maxsize<0
ret = ItemStorageHelper.pbDeleteItem(@pockets[pocket],maxsize,item,qty)
return ret
end
def registeredItems
@registeredItems = [] if !@registeredItems
if @registeredItem && @registeredItem>0 && !@registeredItems.include?(@registeredItem)
@registeredItems.push(@registeredItem)
@registeredItem = nil
end
return @registeredItems
end
def registeredItem; return registeredItems; end
def pbIsRegistered?(item)
registeredlist = self.registeredItems
return registeredlist.include?(item)
end
# Registers the item in the Ready Menu.
def pbRegisterItem(item)
item = getID(PBItems,item)
if !item || item<1
raise ArgumentError.new(_INTL("Item number {1} is invalid.",item))
return
end
registeredlist = self.registeredItems
registeredlist.push(item) if !registeredlist.include?(item)
end
# Unregisters the item from the Ready Menu.
def pbUnregisterItem(item)
item = getID(PBItems,item)
if !item || item<1
raise ArgumentError.new(_INTL("Item number {1} is invalid.",item))
return
end
registeredlist = self.registeredItems
if registeredlist.include?(item)
for i in 0...registeredlist.length
next if registeredlist[i]!=item
registeredlist[i] = nil
break
end
registeredlist.compact!
end
end
def registeredIndex
@registeredIndex = [0,0,1] if !@registeredIndex
return @registeredIndex
end
end
#===============================================================================
# The PC item storage object, which actually contains all the items
#===============================================================================
class PCItemStorage
MAXSIZE = 50 # Number of different slots in storage
MAXPERSLOT = 999 # Max. number of items per slot
def initialize
@items = []
# Start storage with a Potion
pbStoreItem(getConst(PBItems,:POTION)) if hasConst?(PBItems,:POTION)
end
def [](i)
@items[i]
end
def length
@items.length
end
def empty?
return @items.length==0
end
def clear
@items.clear
end
def getItem(index)
return (index<0 || index>=@items.length) ? 0 : @items[index][0]
end
def getCount(index)
return (index<0 || index>=@items.length) ? 0 : @items[index][1]
end
def pbQuantity(item)
return ItemStorageHelper.pbQuantity(@items,MAXSIZE,item)
end
def pbCanStore?(item,qty=1)
return ItemStorageHelper.pbCanStore?(@items,MAXSIZE,MAXPERSLOT,item,qty)
end
def pbStoreItem(item,qty=1)
return ItemStorageHelper.pbStoreItem(@items,MAXSIZE,MAXPERSLOT,item,qty)
end
def pbDeleteItem(item,qty=1)
return ItemStorageHelper.pbDeleteItem(@items,MAXSIZE,item,qty)
end
end
#===============================================================================
# Implements methods that act on arrays of items. Each element in an item
# array is itself an array of [itemID, itemCount].
# Used by the Bag, PC item storage, and Triple Triad.
#===============================================================================
module ItemStorageHelper
# Returns the quantity of the given item in the items array, maximum size per
# slot, and item ID
def self.pbQuantity(items,maxsize,item)
ret = 0
for i in 0...maxsize
itemslot = items[i]
ret += itemslot[1] if itemslot && itemslot[0]==item
end
return ret
end
# Deletes an item (items array, max. size per slot, item, no. of items to delete)
def self.pbDeleteItem(items,maxsize,item,qty)
raise "Invalid value for qty: #{qty}" if qty<0
return true if qty==0
ret = false
for i in 0...maxsize
itemslot = items[i]
next if !itemslot || itemslot[0]!=item
amount = [qty,itemslot[1]].min
itemslot[1] -= amount
qty -= amount
items[i] = nil if itemslot[1]==0
next if qty>0
ret = true
break
end
items.compact!
return ret
end
def self.pbCanStore?(items,maxsize,maxPerSlot,item,qty)
raise "Invalid value for qty: #{qty}" if qty<0
return true if qty==0
for i in 0...maxsize
itemslot = items[i]
if !itemslot
qty -= [qty,maxPerSlot].min
return true if qty==0
elsif itemslot[0]==item && itemslot[1]<maxPerSlot
newamt = itemslot[1]
newamt = [newamt+qty,maxPerSlot].min
qty -= (newamt-itemslot[1])
return true if qty==0
end
end
return false
end
def self.pbStoreItem(items,maxsize,maxPerSlot,item,qty,sorting=false)
raise "Invalid value for qty: #{qty}" if qty<0
return true if qty==0
itemPocket = pbGetPocket(item)
for i in 0...maxsize
itemslot = items[i]
if !itemslot
items[i] = [item,[qty,maxPerSlot].min]
qty -= items[i][1]
items.sort! if sorting && BAG_POCKET_AUTO_SORT[itemPocket]
return true if qty==0
elsif itemslot[0]==item && itemslot[1]<maxPerSlot
newamt = itemslot[1]
newamt = [newamt+qty,maxPerSlot].min
qty -= (newamt-itemslot[1])
itemslot[1] = newamt
return true if qty==0
end
end
return false
end
end
#===============================================================================
# Shortcut methods
#===============================================================================
def pbQuantity(*args)
return $PokemonBag.pbQuantity(*args)
end
def pbHasItem?(*args)
return $PokemonBag.pbHasItem?(*args)
end
def pbCanStore?(*args)
return $PokemonBag.pbCanStore?(*args)
end
def pbStoreItem(*args)
return $PokemonBag.pbStoreItem(*args)
end
def pbStoreAllOrNone(*args)
return $PokemonBag.pbStoreAllOrNone(*args)
end