Minor fixes for previous commit

This commit is contained in:
Maruno17
2021-04-17 23:56:51 +01:00
parent 2ca8a42949
commit f10fe5c491
20 changed files with 5 additions and 3 deletions

View File

@@ -0,0 +1,740 @@
#===============================================================================
# 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
def pbCanRegisterItem?(item)
return ItemHandlers.hasUseInFieldHandler(item)
end
def pbCanUseOnPokemon?(item)
return ItemHandlers.hasUseOnPokemon(item) || GameData::Item.get(item).is_machine?
end
#===============================================================================
# Change a Pokémon's level
#===============================================================================
def pbChangeLevel(pkmn,newlevel,scene)
newlevel = newlevel.clamp(1, GameData::GrowthRate.max_level)
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.calc_stats
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
pkmn.level = newlevel
pkmn.changeHappiness("vitamin")
pkmn.calc_stats
scene.pbRefresh
if scene.is_a?(PokemonPartyScreen)
scene.pbDisplay(_INTL("{1} grew to Lv. {2}!",pkmn.name,pkmn.level))
else
pbMessage(_INTL("{1} grew to Lv. {2}!",pkmn.name,pkmn.level))
end
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),scene)
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),scene)
# Learn new moves upon level up
movelist = pkmn.getMoveList
for i in movelist
next if i[0]!=pkmn.level
pbLearnMove(pkmn,i[1],true) { scene.pbUpdate }
end
# Check for evolution
newspecies = pkmn.check_evolution_on_level_up
if newspecies
pbFadeOutInWithMusic {
evo = PokemonEvolutionScene.new
evo.pbStartScreen(pkmn,newspecies)
evo.pbEvolution
evo.pbEndScreen
scene.pbRefresh if scene.is_a?(PokemonPartyScreen)
}
end
end
end
def pbTopRightWindow(text, scene = nil)
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
scene.pbUpdate if scene
break if Input.trigger?(Input::USE)
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
return 0 if pkmn.moves[idxMove].total_pp<=0
oldpp = pkmn.moves[idxMove].pp
newpp = pkmn.moves[idxMove].pp+pp
newpp = pkmn.moves[idxMove].total_pp if newpp>pkmn.moves[idxMove].total_pp
pkmn.moves[idxMove].pp = newpp
return newpp-oldpp
end
def pbBattleRestorePP(pkmn, battler, idxMove, pp)
return 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
#===============================================================================
# Change EVs
#===============================================================================
def pbJustRaiseEffortValues(pkmn, stat, evGain)
stat = GameData::Stat.get(stat).id
evTotal = 0
GameData::Stat.each_main { |s| evTotal += pkmn.ev[s.id] }
evGain = evGain.clamp(0, Pokemon::EV_STAT_LIMIT - pkmn.ev[stat])
evGain = evGain.clamp(0, Pokemon::EV_LIMIT - evTotal)
if evGain > 0
pkmn.ev[stat] += evGain
pkmn.calc_stats
end
return evGain
end
def pbRaiseEffortValues(pkmn, stat, evGain = 10, ev_limit = true)
stat = GameData::Stat.get(stat).id
return 0 if ev_limit && pkmn.ev[stat] >= 100
evTotal = 0
GameData::Stat.each_main { |s| evTotal += pkmn.ev[s.id] }
evGain = evGain.clamp(0, Pokemon::EV_STAT_LIMIT - pkmn.ev[stat])
evGain = evGain.clamp(0, 100 - pkmn.ev[stat]) if ev_limit
evGain = evGain.clamp(0, Pokemon::EV_LIMIT - evTotal)
if evGain > 0
pkmn.ev[stat] += evGain
pkmn.calc_stats
end
return evGain
end
def pbRaiseHappinessAndLowerEV(pkmn,scene,stat,messages)
h = pkmn.happiness<255
e = pkmn.ev[stat]>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[stat] -= 10
pkmn.ev[stat] = 0 if pkmn.ev[stat]<0
pkmn.calc_stats
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.diving ||
(!$PokemonGlobal.bicycle && $game_player.pbTerrainTag.must_walk)
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
map_metadata = GameData::MapMetadata.try_get($game_map.map_id)
if $PokemonGlobal.bicycle
if map_metadata && map_metadata.always_bicycle
pbMessage(_INTL("You can't dismount your Bike here."))
return false
end
return true
end
if !map_metadata || (!map_metadata.can_bicycle && !map_metadata.outdoor_map)
pbMessage(_INTL("Can't use that here."))
return false
end
return true
end
#===============================================================================
# Find the closest hidden item (for Itemfinder)
#===============================================================================
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
move = GameData::Move.get(move).id
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
movename = GameData::Move.get(move).name
if pkmn.hasMove?(move)
pbMessage(_INTL("{1} already knows {2}.",pkmnname,movename),&block) if !ignoreifknown
return false
end
if pkmn.numMoves<Pokemon::MAX_MOVES
pkmn.learn_move(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 = pkmn.moves[forgetmove].name
oldmovepp = pkmn.moves[forgetmove].pp
pkmn.moves[forgetmove] = Pokemon::Move.new(move) # Replaces current/total PP
if bymachine && Settings::TAUGHT_MACHINES_KEEP_OLD_PP
pkmn.moves[forgetmove].pp = [oldmovepp,pkmn.moves[forgetmove].total_pp].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
#===============================================================================
# Use an item from the Bag and/or on a Pokémon
#===============================================================================
# @return [Integer] 0 = item wasn't used; 1 = item used; 2 = close Bag to use in field
def pbUseItem(bag,item,bagscene=nil)
itm = GameData::Item.get(item)
useType = itm.field_use
if itm.is_machine? # TM or HM
if $Trainer.pokemon_count == 0
pbMessage(_INTL("There is no Pokémon."))
return 0
end
machine = itm.move
return 0 if !machine
movename = GameData::Move.get(machine).name
pbMessage(_INTL("\\se[PC access]You booted up {1}.\1",itm.name))
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 itm.is_TR?
return 1
end
return 0
elsif useType==1 || useType==5 # Item is usable on a Pokémon
if $Trainer.pokemon_count == 0
pbMessage(_INTL("There is no Pokémon."))
return 0
end
ret = false
annot = nil
if itm.is_evolution_stone?
annot = []
for pkmn in $Trainer.party
elig = pkmn.check_evolution_on_use_item(item)
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}.",itm.name)) { screen.pbUpdate }
break
end
end
end
end
screen.pbEndScene
bagscene.pbRefresh if bagscene
}
return (ret) ? 1 : 0
elsif useType==2 # Item is usable from Bag
intret = ItemHandlers.triggerUseFromBag(item)
case intret
when 0 then return 0
when 1 then return 1 # Item used
when 2 then return 2 # Item used, end screen
when 3 # Item used, consume item
bag.pbDeleteItem(item)
return 1
when 4 # Item used, end screen and consume item
bag.pbDeleteItem(item)
return 2
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)
itm = GameData::Item.get(item)
# TM or HM
if itm.is_machine?
machine = itm.move
return false if !machine
movename = GameData::Move.get(machine).name
if pkmn.shadowPokemon?
pbMessage(_INTL("Shadow Pokémon can't be taught any moves.")) { scene.pbUpdate }
elsif !pkmn.compatible_with_move?(machine)
pbMessage(_INTL("{1} can't learn {2}.",pkmn.name,movename)) { scene.pbUpdate }
else
pbMessage(_INTL("\\se[PC access]You booted up {1}.\1",itm.name)) { scene.pbUpdate }
if pbConfirmMessage(_INTL("Do you want to teach {1} to {2}?",movename,pkmn.name)) { scene.pbUpdate }
if pbLearnMove(pkmn,machine,false,true) { scene.pbUpdate }
$PokemonBag.pbDeleteItem(item) if itm.is_TR?
return true
end
end
end
return false
end
# Other item
ret = ItemHandlers.triggerUseOnPokemon(item,pkmn,scene)
scene.pbClearAnnotations
scene.pbHardRefresh
useType = itm.field_use
if ret && useType==1 # Usable on Pokémon, consumed
$PokemonBag.pbDeleteItem(item)
if !$PokemonBag.pbHasItem?(item)
pbMessage(_INTL("You used your last {1}.",itm.name)) { scene.pbUpdate }
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 = GameData::Item.get(item).name
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 = GameData::Item.get(item).name
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 = pkmn.item.name
if pkmn.hasItem?(: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 GameData::Item.get(item).is_mail?
if pbWriteMail(item,pkmn,pkmnid,scene)
pkmn.item = 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.item = 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 !GameData::Item.get(item).is_mail? || pbWriteMail(item,pkmn,pkmnid,scene)
$PokemonBag.pbDeleteItem(item)
pkmn.item = 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.item = nil
ret = true
end
elsif scene.pbConfirm(_INTL("If the mail is removed, its message will be lost. OK?"))
$PokemonBag.pbStoreItem(pkmn.item)
scene.pbDisplay(_INTL("Received the {1} from {2}.",pkmn.item.name,pkmn.name))
pkmn.item = nil
pkmn.mail = nil
ret = true
end
else
$PokemonBag.pbStoreItem(pkmn.item)
scene.pbDisplay(_INTL("Received the {1} from {2}.",pkmn.item.name,pkmn.name))
pkmn.item = nil
ret = true
end
return ret
end
#===============================================================================
# Choose an item from the Bag
#===============================================================================
def pbChooseItem(var = 0, *args)
ret = nil
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 = nil
pbFadeOutIn {
scene = PokemonBag_Scene.new
screen = PokemonBagScreen.new(scene,$PokemonBag)
ret = screen.pbChooseItemScreen(Proc.new { |item| GameData::Item.get(item).is_apricorn? })
}
$game_variables[var] = ret if var > 0
return ret
end
def pbChooseFossil(var = 0)
ret = nil
pbFadeOutIn {
scene = PokemonBag_Scene.new
screen = PokemonBagScreen.new(scene,$PokemonBag)
ret = screen.pbChooseItemScreen(Proc.new { |item| GameData::Item.get(item).is_fossil? })
}
$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 !GameData::Item.exists?(item)
itm = GameData::Item.get(item)
next if !$PokemonBag.pbHasItem?(itm)
commands.push(itm.name)
itemid.push(itm.id)
end
if commands.length == 0
$game_variables[variable] = 0
return nil
end
commands.push(_INTL("Cancel"))
itemid.push(nil)
ret = pbMessage(message, commands, -1)
if ret < 0 || ret >= commands.length-1
$game_variables[variable] = nil
return nil
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,681 @@
#===============================================================================
# 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
if !battle.canRun
scene.pbDisplay(_INTL("You can't escape!")) if showMessages
next false
end
next true
})
ItemHandlers::CanUseInBattle.copy(:POKEDOLL,:FLUFFYTAIL,:POKETOY)
ItemHandlers::CanUseInBattle.addIf(proc { |item| GameData::Item.get(item).is_poke_ball? }, # Poké Balls
proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if battle.pbPlayer.party_full? && $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 && !(GameData::Item.get(item).is_snag_ball? && 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 !Settings::RAGE_CANDY_BAR_CURES_STATUS_PROBLEMS
ItemHandlers::CanUseInBattle.add(:AWAKENING,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanCureStatus?(: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?(:SLEEP, pokemon, scene, showMessages)
})
ItemHandlers::CanUseInBattle.add(:ANTIDOTE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanCureStatus?(:POISON, pokemon, scene, showMessages)
})
ItemHandlers::CanUseInBattle.copy(:ANTIDOTE,:PECHABERRY)
ItemHandlers::CanUseInBattle.add(:BURNHEAL,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanCureStatus?(:BURN, pokemon, scene, showMessages)
})
ItemHandlers::CanUseInBattle.copy(:BURNHEAL,:RAWSTBERRY)
ItemHandlers::CanUseInBattle.add(:PARALYZEHEAL,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
next pbBattleItemCanCureStatus?(: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?(: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 == :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 Settings::RAGE_CANDY_BAR_CURES_STATUS_PROBLEMS
ItemHandlers::CanUseInBattle.add(:FULLRESTORE,proc { |item,pokemon,battler,move,firstAction,battle,scene,showMessages|
if !pokemon.able? ||
(pokemon.hp == pokemon.totalhp && pokemon.status == :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].total_pp<=0 ||
pokemon.moves[move].pp==pokemon.moves[move].total_pp
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.total_pp<=0 || m.pp==m.total_pp
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?(: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?(: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?(:SPECIAL_ATTACK,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?(:SPECIAL_DEFENSE,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?(: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?(: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 != :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 != :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| GameData::Item.get(item).is_poke_ball? }, # 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 !Settings::RAGE_CANDY_BAR_CURES_STATUS_PROBLEMS
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.heal_status
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.heal_status
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.heal_status
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.heal_status
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.heal_status
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.heal_status
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 Settings::RAGE_CANDY_BAR_CURES_STATUS_PROBLEMS
ItemHandlers::BattleUseOnPokemon.add(:FULLRESTORE,proc { |item,pokemon,battler,choices,scene|
pokemon.heal_status
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.heal_status
scene.pbRefresh
scene.pbDisplay(_INTL("{1} recovered from fainting!",pokemon.name))
})
ItemHandlers::BattleUseOnPokemon.add(:MAXREVIVE,proc { |item,pokemon,battler,choices,scene|
pokemon.heal_HP
pokemon.heal_status
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.heal_status
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.heal_HP
pokemon.heal_status
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].total_pp)
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].total_pp)
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(:ATTACK,(Settings::X_STAT_ITEMS_RAISE_BY_TWO_STAGES) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XATTACK2,proc { |item,battler,scene|
battler.pbRaiseStatStage(:ATTACK,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XATTACK3,proc { |item,battler,scene|
battler.pbRaiseStatStage(:ATTACK,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XATTACK6,proc { |item,battler,scene|
battler.pbRaiseStatStage(:ATTACK,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XDEFENSE,proc { |item,battler,scene|
battler.pbRaiseStatStage(:DEFENSE,(Settings::X_STAT_ITEMS_RAISE_BY_TWO_STAGES) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XDEFENSE,:XDEFEND)
ItemHandlers::BattleUseOnBattler.add(:XDEFENSE2,proc { |item,battler,scene|
battler.pbRaiseStatStage(:DEFENSE,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XDEFENSE2,:XDEFEND2)
ItemHandlers::BattleUseOnBattler.add(:XDEFENSE3,proc { |item,battler,scene|
battler.pbRaiseStatStage(:DEFENSE,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XDEFENSE3,:XDEFEND3)
ItemHandlers::BattleUseOnBattler.add(:XDEFENSE6,proc { |item,battler,scene|
battler.pbRaiseStatStage(:DEFENSE,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XDEFENSE6,:XDEFEND6)
ItemHandlers::BattleUseOnBattler.add(:XSPATK,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPECIAL_ATTACK,(Settings::X_STAT_ITEMS_RAISE_BY_TWO_STAGES) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XSPATK,:XSPECIAL)
ItemHandlers::BattleUseOnBattler.add(:XSPATK2,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPECIAL_ATTACK,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XSPATK2,:XSPECIAL2)
ItemHandlers::BattleUseOnBattler.add(:XSPATK3,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPECIAL_ATTACK,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XSPATK3,:XSPECIAL3)
ItemHandlers::BattleUseOnBattler.add(:XSPATK6,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPECIAL_ATTACK,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.copy(:XSPATK6,:XSPECIAL6)
ItemHandlers::BattleUseOnBattler.add(:XSPDEF,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPECIAL_DEFENSE,(Settings::X_STAT_ITEMS_RAISE_BY_TWO_STAGES) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPDEF2,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPECIAL_DEFENSE,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPDEF3,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPECIAL_DEFENSE,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPDEF6,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPECIAL_DEFENSE,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPEED,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPEED,(Settings::X_STAT_ITEMS_RAISE_BY_TWO_STAGES) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPEED2,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPEED,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPEED3,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPEED,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XSPEED6,proc { |item,battler,scene|
battler.pbRaiseStatStage(:SPEED,6,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XACCURACY,proc { |item,battler,scene|
battler.pbRaiseStatStage(:ACCURACY,(Settings::X_STAT_ITEMS_RAISE_BY_TWO_STAGES) ? 2 : 1,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XACCURACY2,proc { |item,battler,scene|
battler.pbRaiseStatStage(:ACCURACY,2,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XACCURACY3,proc { |item,battler,scene|
battler.pbRaiseStatStage(:ACCURACY,3,battler)
battler.pokemon.changeHappiness("battleitem")
})
ItemHandlers::BattleUseOnBattler.add(:XACCURACY6,proc { |item,battler,scene|
battler.pbRaiseStatStage(: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,304 @@
#===============================================================================
# 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.has_pokegear # Can't register without a Pokégear
return false if !GameData::TrainerType.exists?(trainertype)
trainertype = GameData::TrainerType.get(trainertype)
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}", GameData::TrainerType.get(trainertype).name,
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 = []
this_map_metadata = GameData::MapMetadata.try_get($game_map.map_id)
return nil if !this_map_metadata || !this_map_metadata.town_map_position
currentRegion = this_map_metadata.town_map_position[0]
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
caller_map_metadata = GameData::MapMetadata.try_get(num[6])
next if !caller_map_metadata || !caller_map_metadata.town_map_position
# Can't call if in different region
next if caller_map_metadata.town_map_position[0] != currentRegion
temparray.push(num)
end
return nil if temparray.length==0
return temparray[rand(temparray.length)]
end
def pbFindPhoneTrainer(tr_type, tr_name) # Ignores whether visible or not
return nil if !$PokemonGlobal.phoneNumbers
tr_type = GameData::TrainerType.get(tr_type).id
for num in $PokemonGlobal.phoneNumbers
return num if num[1] == tr_type && num[2] == tr_name # If a match
end
return nil
end
def pbHasPhoneTrainer?(tr_type, tr_name)
return pbFindPhoneTrainer(tr_type, tr_name) != nil
end
def pbPhoneBattleCount(tr_type, tr_name)
trainer = pbFindPhoneTrainer(tr_type, tr_name)
return (trainer) ? trainer[5] : 0
end
def pbPhoneReadyToBattle?(tr_type, tr_name)
trainer = pbFindPhoneTrainer(tr_type, tr_name)
return (trainer && trainer[4]>=2)
end
#===============================================================================
# Contact rematch data modifications
#===============================================================================
def pbPhoneIncrement(tr_type, tr_name, maxbattles)
trainer = pbFindPhoneTrainer(tr_type, tr_name)
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(tr_type, tr_name)
trainer = pbFindPhoneTrainer(tr_type, tr_name)
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.has_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
caller_map_metadata = GameData::MapMetadata.try_get(trainer[6])
this_map_metadata = GameData::MapMetadata.try_get($game_map.map_id)
if !caller_map_metadata || !caller_map_metadata.town_map_position ||
!this_map_metadata || !this_map_metadata.town_map_position ||
caller_map_metadata.town_map_position[0] != this_map_metadata.town_map_position[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)
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(enc_table)
return nil if !enc_table || enc_table.length == 0
len = [enc_table.length, 4].min
return enc_table[rand(len)][1]
end
def pbEncounterSpecies(phonenum)
return "" if !phonenum[6] || phonenum[6] == 0
encounter_data = GameData::Encounter.get(phonenum[6], $PokemonGlobal.encounter_version)
return "" if !encounter_data
enc_tables = encounter_data.types
species = pbRandomEncounterSpecies(enc_tables[:Land])
if !species
species = pbRandomEncounterSpecies(enc_tables[:Cave])
if !species
species = pbRandomEncounterSpecies(enc_tables[:Water])
end
end
return "" if !species
return GameData::Species.get(species).name
end
def pbTrainerSpecies(phonenum)
return "" if !phonenum[0]
partyid = [0, phonenum[5] - 1].max
trainer_data = GameData::Trainer.try_get(phonenum[1], phonenum[2], partyid)
return "" if !trainer_data
if trainer_data.pokemon.length == 1
pkmn = trainer_data.pokemon[0][:species]
else
pkmn = trainer_data.pokemon[rand(trainer_data.pokemon.length)][:species]
end
return GameData::Species.get(pkmn).name
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,240 @@
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
terrain = $game_map.terrain_tag($game_player.x,$game_player.y)
if !terrain.land_wild_encounters || !terrain.shows_grass_rustle
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.has_normal_land_encounters?
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 pbPokeRadarCancel
$PokemonTemp.pokeradar = nil
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
terrain = $game_map.terrain_tag(x, y)
if terrain.land_wild_encounters && terrain.shows_grass_rustle
# Choose a rarity for the grass (0=normal, 1=rare, 2=shiny)
s = (rand(100) < 25) ? 1 : 0
if $PokemonTemp.pokeradar && $PokemonTemp.pokeradar[2] > 0
v = [(65536 / Settings::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(Settings::RUSTLE_NORMAL_ANIMATION_ID,grass[0],grass[1],true,1)
when 1 # Vigorous rustle
$scene.spriteset.addUserAnimation(Settings::RUSTLE_VIGOROUS_ANIMATION_ID,grass[0],grass[1],true,1)
when 2 # Shiny rustle
$scene.spriteset.addUserAnimation(Settings::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 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
array = []
Settings::POKE_RADAR_ENCOUNTERS.each do |enc|
array.push(enc) if enc[0] == map && GameData::Species.exists?(enc[2])
end
# If there are any exclusives, first have a chance of encountering those
if array.length > 0
rnd = rand(100)
chance = 0
array.each do |enc|
rnd -= enc[1]
next if rnd >= 0
level = (enc[4] && enc[4] > enc[3]) ? rand(enc[3]..enc[4]) : enc[3]
return [enc[2], level]
end
end
end
# Didn't choose a Poké Radar-exclusive species, choose a regular encounter instead
return $PokemonEncounters.choose_wild_pokemon($PokemonEncounters.encounter_type, rarity + 1)
end
################################################################################
# Event handlers
################################################################################
EncounterModifier.register(proc { |encounter|
if GameData::EncounterType.get($PokemonTemp.encounterType).type != :land ||
$PokemonGlobal.bicycle || $PokemonGlobal.partner
pbPokeRadarCancel
next encounter
end
ring = pbPokeRadarGetShakingGrass
if ring >= 0 # Encounter triggered by stepping into rustling grass
# Get rarity of shaking grass
rarity = 0 # 0 = rustle, 1 = vigorous rustle, 2 = shiny rustle
$PokemonTemp.pokeradar[3].each { |g| rarity = g[3] if g[2] == ring }
if $PokemonTemp.pokeradar[2] > 0 # Chain count, i.e. is chaining
if rarity == 2 || rand(100) < 86 + ring * 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.choose_wild_pokemon($PokemonEncounters.encounter_type)
end
pbPokeRadarCancel
end
else # Not chaining; will start one
# Force random wild encounter, vigorous shaking means rarer species
encounter = pbPokeRadarGetEncounter(rarity)
$PokemonTemp.forceSingleBattle = true
end
else # Encounter triggered by stepping in non-rustling grass
pbPokeRadarCancel if encounter
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.shiny = true if grass[3]==2
break
end
}
Events.onWildBattleEnd += proc { |_sender,e|
species = e[0]
level = e[1]
decision = e[2]
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
terrain = $game_map.terrain_tag($game_player.x,$game_player.y)
if !terrain.land_wild_encounters || !terrain.shows_grass_rustle
pbPokeRadarCancel
end
}
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,134 @@
# Data structure representing mail that the Pokémon can hold
class Mail
attr_accessor :item, :message, :sender, :poke1, :poke2, :poke3
def initialize(item, message, sender, poke1 = nil, poke2 = nil, poke3 = nil)
@item = GameData::Item.get(item).id # 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
# @deprecated Use {Mail} instead. PokemonMail is slated to be removed in v20.
class PokemonMail
attr_reader :item, :message, :sender, :poke1, :poke2, :poke3
def self.convert(mail)
return mail if mail.is_a?(Mail)
item.poke1[0] = GameData::Species.get(item.poke1[0]).id if item.poke1
item.poke2[0] = GameData::Species.get(item.poke2[0]).id if item.poke2
item.poke3[0] = GameData::Species.get(item.poke3[0]).id if item.poke3
return Mail.new(mail.item, item.message, item.sender, item.poke1, item.poke2, item.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 = Mail.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(GameData::Item.mail_filename(mail.item))
sprites["overlay"] = BitmapSprite.new(Graphics.width,Graphics.height,viewport)
overlay = sprites["overlay"].bitmap
pbSetSystemFont(overlay)
if GameData::Item.get(mail.item).is_icon_mail?
if mail.poke1
sprites["bearer"] = IconSprite.new(64,288,viewport)
bitmapFileName = GameData::Species.icon_filename(mail.poke1[0],
mail.poke1[3], mail.poke1[1], mail.poke1[2], mail.poke1[4], 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 = GameData::Species.icon_filename(mail.poke2[0],
mail.poke2[3], mail.poke2[1], mail.poke2[2], mail.poke2[4], 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 = GameData::Species.icon_filename(mail.poke3[0],
mail.poke3[3], mail.poke3[1], mail.poke3[2], mail.poke3[4], 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::BACK) || Input.trigger?(Input::USE)
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. 250 characters)."),
"",false,250,Graphics.width) { scene.pbUpdate }
if message!=""
# Store mail if a message was written
poke1 = poke2 = nil
if $Trainer.party[pkmnid+2]
p = $Trainer.party[pkmnid+2]
poke1 = [p.species,p.gender,p.shiny?,p.form,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,p.shadowPokemon?]
poke2.push(true) if p.egg?
end
poke3 = [pkmn.species,pkmn.gender,pkmn.shiny?,pkmn.form,pkmn.shadowPokemon?]
poke3.push(true) if pkmn.egg?
pbStoreMail(pkmn,item,message,poke1,poke2,poke3)
return true
end
return false if scene.pbConfirm(_INTL("Stop giving the Pokémon Mail?"))
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
@blankzero = false
@forceitemchange = true
self.item = item
@forceitemchange = 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 || !@blankzero
@animbitmap = AnimatedBitmap.new(GameData::Item.icon_filename(@item))
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 = nil
self.item = @pokemon.item_id
end
def dispose
@animbitmap.dispose if @animbitmap
super
end
def pokemon=(value)
@pokemon = value
self.item = @pokemon.item_id
end
def item=(value)
return if @item==value
@item = value
@animbitmap.dispose if @animbitmap
@animbitmap = nil
if @item
@animbitmap = AnimatedBitmap.new(GameData::Item.held_icon_filename(@item))
self.bitmap = @animbitmap.bitmap
else
self.bitmap = nil
end
end
def update
super
self.item = @pokemon.item_id
if @animbitmap
@animbitmap.update
self.bitmap = @animbitmap.bitmap
end
end
end

View File

@@ -0,0 +1,351 @@
#===============================================================================
# The Bag object, which actually contains all the items
#===============================================================================
class PokemonBag
attr_accessor :lastpocket
def self.pocketNames
return Settings.bag_pocket_names
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
num_pockets = PokemonBag.numPockets
for i in 0...[@pockets.length, num_pockets].min
for item in @pockets[i]
p = GameData::Item.get(item[0]).pocket
newpockets[p].push(item)
end
end
@pockets = newpockets
end
end
def clear
@pockets.each { |pocket| pocket.clear }
end
def pockets
rearrange
return @pockets
end
def maxPocketSize(pocket)
maxsize = Settings::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 = GameData::Item.get(item)
pocket = item.pocket
return ItemStorageHelper.pbQuantity(@pockets[pocket], item.id)
end
def pbHasItem?(item)
return pbQuantity(item) > 0
end
def pbCanStore?(item, qty = 1)
item = GameData::Item.get(item)
pocket = item.pocket
maxsize = maxPocketSize(pocket)
maxsize = @pockets[pocket].length + 1 if maxsize < 0
return ItemStorageHelper.pbCanStore?(
@pockets[pocket], maxsize, Settings::BAG_MAX_PER_SLOT, item.id, qty)
end
def pbStoreItem(item, qty = 1)
item = GameData::Item.get(item)
pocket = item.pocket
maxsize = maxPocketSize(pocket)
maxsize = @pockets[pocket].length + 1 if maxsize < 0
return ItemStorageHelper.pbStoreItem(
@pockets[pocket], maxsize, Settings::BAG_MAX_PER_SLOT, item.id, qty, true)
end
def pbStoreAllOrNone(item, qty = 1)
return false if !pbCanStore?(item, qty)
return pbStoreItem(item, qty)
end
def pbChangeItem(old_item, new_item)
old_item = GameData::Item.get(old_item)
new_item = GameData::Item.get(new_item)
pocket = old_item.pocket
ret = false
@pockets[pocket].each do |item|
next if !item || item[0] != old_item.id
item[0] = new_item.id
ret = true
end
return ret
end
def pbChangeQuantity(pocket, index, newqty = 1)
return false if pocket <= 0 || pocket > self.numPockets
return false if !@pockets[pocket][index]
newqty = [newqty, maxPocketSize(pocket)].min
@pockets[pocket][index][1] = newqty
return true
end
def pbDeleteItem(item, qty = 1)
item = GameData::Item.get(item)
pocket = item.pocket
ret = ItemStorageHelper.pbDeleteItem(@pockets[pocket], item.id, qty)
return ret
end
def registeredItems
@registeredItems = [] if !@registeredItems
return @registeredItems
end
def pbIsRegistered?(item)
item = GameData::Item.get(item).id
registeredlist = self.registeredItems
return registeredlist.include?(item)
end
# Registers the item in the Ready Menu.
def pbRegisterItem(item)
item = GameData::Item.get(item).id
registeredlist = self.registeredItems
registeredlist.push(item) if !registeredlist.include?(item)
end
# Unregisters the item from the Ready Menu.
def pbUnregisterItem(item)
item = GameData::Item.get(item).id
registeredlist = self.registeredItems
for i in 0...registeredlist.length
next if registeredlist[i] != item
registeredlist[i] = nil
break
end
registeredlist.compact!
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
attr_reader :items
MAX_SIZE = 999 # Number of different slots in storage
MAX_PER_SLOT = 999 # Max. number of items per slot
def initialize
@items = []
# Start storage with a Potion
pbStoreItem(:POTION) if GameData::Item.exists?(:POTION)
end
def [](i)
return @items[i]
end
def length
return @items.length
end
def empty?
return @items.length == 0
end
def clear
@items.clear
end
def getItem(index)
return (index < 0 || index >= @items.length) ? nil : @items[index][0]
end
def getCount(index)
return (index < 0 || index >= @items.length) ? 0 : @items[index][1]
end
def pbQuantity(item)
item = GameData::Item.get(item).id
return ItemStorageHelper.pbQuantity(@items, item)
end
def pbCanStore?(item, qty = 1)
item = GameData::Item.get(item).id
return ItemStorageHelper.pbCanStore?(@items, MAX_SIZE, MAX_PER_SLOT, item, qty)
end
def pbStoreItem(item, qty = 1)
item = GameData::Item.get(item).id
return ItemStorageHelper.pbStoreItem(@items, MAX_SIZE, MAX_PER_SLOT, item, qty)
end
def pbDeleteItem(item, qty = 1)
item = GameData::Item.get(item).id
return ItemStorageHelper.pbDeleteItem(@items, 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 check_item in item_array
def self.pbQuantity(item_array, check_item)
ret = 0
item_array.each { |i| ret += i[1] if i && i[0] == check_item }
return ret
end
# Deletes an item (items array, max. size per slot, item, no. of items to delete)
def self.pbDeleteItem(items, item, qty)
raise "Invalid value for qty: #{qty}" if qty < 0
return true if qty == 0
ret = false
for i in 0...items.length
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
itm = GameData::Item.try_get(item)
itemPocket = (itm) ? itm.pocket : 0
for i in 0...maxsize
itemslot = items[i]
if !itemslot
items[i] = [item, [qty, maxPerSlot].min]
qty -= items[i][1]
if itemPocket > 0 && sorting && Settings::BAG_POCKET_AUTO_SORT[itemPocket]
items.sort! { |a, b| GameData::Item.get(a[0]).id_number <=> GameData::Item.get(b[0]).id_number }
end
return true if qty == 0
elsif itemslot[0] == item && itemslot[1] < maxPerSlot
newamt = itemslot[1]
newamt = [newamt + qty, maxPerSlot].min
qty -= (newamt - itemslot[1])
itemslot[1] = newamt
return true if qty == 0
end
end
return false
end
end
#===============================================================================
# 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