Added Gen 9 forms code, evolution code, some item effects

This commit is contained in:
Maruno17
2024-06-08 19:35:45 +01:00
parent 6c3d9e77ad
commit 5e23984765
26 changed files with 678 additions and 495 deletions

View File

@@ -5,6 +5,7 @@ module GameData
attr_reader :parameter
attr_reader :any_level_up # false means parameter is the minimum level
attr_reader :level_up_proc
attr_reader :battle_level_up_proc
attr_reader :use_item_proc
attr_reader :on_trade_proc
attr_reader :after_battle_proc
@@ -25,6 +26,7 @@ module GameData
@parameter = hash[:parameter]
@any_level_up = hash[:any_level_up] || false
@level_up_proc = hash[:level_up_proc]
@battle_level_up_proc = hash[:battle_level_up_proc]
@use_item_proc = hash[:use_item_proc]
@on_trade_proc = hash[:on_trade_proc]
@after_battle_proc = hash[:after_battle_proc]
@@ -38,6 +40,15 @@ module GameData
return (@level_up_proc) ? @level_up_proc.call(*args) : nil
end
def call_battle_level_up(*args)
if @battle_level_up_proc
return @battle_level_up_proc.call(*args)
elsif @level_up_proc
return @level_up_proc.call(*args)
end
return nil
end
def call_use_item(*args)
return (@use_item_proc) ? @use_item_proc.call(*args) : nil
end
@@ -198,19 +209,15 @@ GameData::Evolution.register({
}
})
GameData::Evolution.register({
:id => :LevelBattle,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter
}
})
GameData::Evolution.register({
:id => :LevelCoins,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next $player.coins >= parameter
},
:after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species|
$player.coins -= parameter
next true
}
})
@@ -528,11 +535,26 @@ GameData::Evolution.register({
:any_level_up => true, # Needs any level up
:level_up_proc => proc { |pkmn, parameter|
next pkmn.evolution_counter >= parameter
},
:after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species|
pkmn.evolution_counter = 0
next true
}
})
#===============================================================================
# Evolution methods that trigger when using an item on the Pokémon
# Evolution methods that trigger when levelling up in battle.
#===============================================================================
GameData::Evolution.register({
:id => :LevelBattle,
:parameter => Integer,
:battle_level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter
}
})
#===============================================================================
# Evolution methods that trigger when using an item on the Pokémon.
#===============================================================================
GameData::Evolution.register({
:id => :Item,
@@ -583,7 +605,7 @@ GameData::Evolution.register({
})
#===============================================================================
# Evolution methods that trigger when the Pokémon is obtained in a trade
# Evolution methods that trigger when the Pokémon is obtained in a trade.
#===============================================================================
GameData::Evolution.register({
:id => :Trade,
@@ -637,25 +659,39 @@ GameData::Evolution.register({
:id => :TradeSpecies,
:parameter => :Species,
:on_trade_proc => proc { |pkmn, parameter, other_pkmn|
next pkmn.species == parameter && !other_pkmn.hasItem?(:EVERSTONE)
next other_pkmn.species == parameter && !other_pkmn.hasItem?(:EVERSTONE)
}
})
#===============================================================================
# Evolution methods that are triggered after any battle
# Evolution methods that are triggered after any battle.
#===============================================================================
GameData::Evolution.register({
:id => :BattleDealCriticalHit,
:id => :AfterBattleCounter,
:parameter => Integer,
:any_level_up => true, # Needs any level up
:after_battle_proc => proc { |pkmn, party_index, parameter|
next $game_temp.party_critical_hits_dealt &&
$game_temp.party_critical_hits_dealt[party_index] &&
$game_temp.party_critical_hits_dealt[party_index] >= parameter
ret = pkmn.evolution_counter >= parameter
pkmn.evolution_counter = 0 # Always resets after battle
next ret
}
})
# Doesn't cause an evolution itself. Just makes the Pokémon ready to evolve by
# another means (e.g. via an event). Note that pkmn.evolution_counter is not
# reset after the battle.
GameData::Evolution.register({
:id => :AfterBattleCounterMakeReady,
:parameter => Integer,
:any_level_up => true, # Needs any level up
:after_battle_proc => proc { |pkmn, party_index, parameter|
pkmn.ready_to_evolve = true if pkmn.evolution_counter >= parameter
next false
}
})
#===============================================================================
# Evolution methods that are triggered by an event
# Evolution methods that are triggered by an event.
# Each event has its own number, which is the value of the parameter as defined
# in pokemon.txt/pokemon_forms.txt. It is also 'number' in def pbEvolutionEvent,
# which triggers evolution checks for a particular event number. 'value' in an
@@ -685,17 +721,9 @@ GameData::Evolution.register({
})
GameData::Evolution.register({
:id => :EventAfterDamageTaken,
:parameter => Integer,
:after_battle_proc => proc { |pkmn, party_index, parameter|
if $game_temp.party_direct_damage_taken &&
$game_temp.party_direct_damage_taken[party_index] &&
$game_temp.party_direct_damage_taken[party_index] >= 49
pkmn.ready_to_evolve = true
end
next false
},
:event_proc => proc { |pkmn, parameter, value|
:id => :EventReady,
:parameter => Integer,
:event_proc => proc { |pkmn, parameter, value|
next value == parameter && pkmn.ready_to_evolve
}
})

View File

@@ -244,7 +244,8 @@ module GameData
:KYOGRE => [:BLUEORB],
:GROUDON => [:REDORB],
:ZACIAN => [:RUSTEDSWORD],
:ZAMAZENTA => [:RUSTEDSHIELD]
:ZAMAZENTA => [:RUSTEDSHIELD],
:OGERPON => [:WELLSPRINGMASK, :HEARTHFLAMEMASK, :CORNERSTONEMASK]
}
return combos[species]&.include?(@id)
end

View File

@@ -166,6 +166,10 @@ module GameData
DATA.each_value { |species| yield species if species.form == 0 }
end
def self.each_form_for_species(species)
DATA.each_value { |species| yield species if species.species == species }
end
def self.species_count
ret = 0
self.each_species { |species| ret += 1 }
@@ -381,7 +385,9 @@ module GameData
return 1 if !prevo_data.incense.nil?
prevo_min_level = prevo_data.minimum_level
evo_method_data = GameData::Evolution.get(evo[1])
return prevo_min_level if evo_method_data.level_up_proc.nil? && evo_method_data.id != :Shedinja
return prevo_min_level if evo_method_data.level_up_proc.nil? &&
evo_method_data.battle_level_up_proc.nil? &&
evo_method_data.id != :Shedinja
any_level_up = evo_method_data.any_level_up
return (any_level_up) ? prevo_min_level + 1 : evo[2]
end

View File

@@ -87,11 +87,6 @@ class Battle::Battler
# Do other things
@battle.pbClearChoice(@index) # Reset choice
pbOwnSide.effects[PBEffects::LastRoundFainted] = @battle.turnCount
if $game_temp.party_direct_damage_taken &&
$game_temp.party_direct_damage_taken[@pokemonIndex] &&
pbOwnedByPlayer?
$game_temp.party_direct_damage_taken[@pokemonIndex] = 0
end
# Check other battlers' abilities that trigger upon a battler fainting
pbAbilitiesOnFainting
# Check for end of primordial weather

View File

@@ -238,6 +238,9 @@ class Battle::Battler
# Record move as having been used
@lastMoveUsed = move.id
@lastMoveUsedType = move.calcType # For Conversion 2
if @pokemon.isSpecies?(:PRIMEAPE) && @lastMoveUsed == :RAGEFIST
@pokemon.evolution_counter += 1
end
if !specialUsage
@lastRegularMoveUsed = move.id # For Disable, Encore, Instruct, Mimic, Mirror Move, Sketch, Spite
@lastRegularMoveTarget = choice[3] # For Instruct (remembering original target is fine)
@@ -707,7 +710,13 @@ class Battle::Battler
move.pbEffectAgainstTarget(user, b)
end
move.pbEffectGeneral(user)
targets.each { |b| b.pbFaint if b&.fainted? }
targets.each do |b|
next if !b&.fainted?
b.pbFaint
if user.pokemon.isSpecies?(:BISHARP) && b.isSpecies?(:BISHARP) && b.item == :LEADERSCREST
user.pokemon.evolution_counter += 1
end
end
user.pbFaint if user.fainted?
# Additional effect
if !user.hasActiveAbility?(:SHEERFORCE)

View File

@@ -297,10 +297,8 @@ class Battle::Move
@battle.pbDisplay(_INTL("The substitute took damage for {1}!", target.pbThis(true)))
end
if target.damageState.critical
if $game_temp.party_critical_hits_dealt &&
$game_temp.party_critical_hits_dealt[user.pokemonIndex] &&
user.pbOwnedByPlayer?
$game_temp.party_critical_hits_dealt[user.pokemonIndex] += 1
if user.pokemon.isSpecies?(:FARFETCHD) && user.pokemon.form == 1
user.pokemon.evolution_counter += 1
end
if target.damageState.affection_critical
if numTargets > 1
@@ -396,10 +394,8 @@ class Battle::Move
target.tookMoveDamageThisRound = true if damage > 0 && !target.damageState.substitute # For Focus Punch
target.tookDamageThisRound = true if damage > 0 # For Assurance
target.lastAttacker.push(user.index) # For Revenge
if $game_temp.party_direct_damage_taken &&
$game_temp.party_direct_damage_taken[target.pokemonIndex] &&
target.pbOwnedByPlayer?
$game_temp.party_direct_damage_taken[target.pokemonIndex] += damage
if target.pokemon.isSpecies?(:YAMASK) && target.pokemon.form == 1
target.pokemon.evolution_counter += damage
end
end
end

View File

@@ -424,6 +424,9 @@ class Battle::Move::RecoilMove < Battle::Move
return if user.hasActiveAbility?(:ROCKHEAD)
amt = pbRecoilDamage(user, target)
amt = 1 if amt < 1
if user.pokemon.isSpecies?(:BASCULIN) && [2, 3].include?(user.pokemon.form)
user.pokemon.evolution_counter += amt
end
user.pbReduceHP(amt, false)
@battle.pbDisplay(_INTL("{1} is damaged by recoil!", user.pbThis))
user.pbItemHPHealCheck

View File

@@ -847,7 +847,8 @@ class Battle::Move::RemoveScreens < Battle::Move
end
#===============================================================================
# User is protected against moves with the "B" flag this round. (Detect, Protect)
# User is protected against moves with the "CanProtect" flag this round.
# (Detect, Protect)
#===============================================================================
class Battle::Move::ProtectUser < Battle::Move::ProtectMove
def initialize(battle, move)
@@ -857,8 +858,8 @@ class Battle::Move::ProtectUser < Battle::Move::ProtectMove
end
#===============================================================================
# User is protected against moves with the "B" flag this round. If a Pokémon
# makes contact with the user while this effect applies, that Pokémon is
# User is protected against moves with the "CanProtect" flag this round. If a
# Pokémon makes contact with the user while this effect applies, that Pokémon is
# poisoned. (Baneful Bunker)
#===============================================================================
class Battle::Move::ProtectUserBanefulBunker < Battle::Move::ProtectMove

View File

@@ -49,13 +49,9 @@ module Battle::CatchAndStoreMixin
if idx < party_size - 1
@initialItems[0][idx] = @initialItems[0][idx + 1]
$game_temp.party_levels_before_battle[idx] = $game_temp.party_levels_before_battle[idx + 1]
$game_temp.party_critical_hits_dealt[idx] = $game_temp.party_critical_hits_dealt[idx + 1]
$game_temp.party_direct_damage_taken[idx] = $game_temp.party_direct_damage_taken[idx + 1]
else
@initialItems[0][idx] = nil
$game_temp.party_levels_before_battle[idx] = nil
$game_temp.party_critical_hits_dealt[idx] = nil
$game_temp.party_direct_damage_taken[idx] = nil
end
end
break

View File

@@ -959,12 +959,14 @@ Battle::ItemEffects::DamageCalcFromUser.add(:NORMALGEM,
}
)
Battle::ItemEffects::DamageCalcFromUser.add(:PIXIEPLATE,
Battle::ItemEffects::DamageCalcFromUser.add(:FAIRYFEATHER,
proc { |item, user, target, move, mults, power, type|
mults[:power_multiplier] *= 1.2 if type == :FAIRY
}
)
Battle::ItemEffects::DamageCalcFromUser.copy(:FAIRYFEATHER, :PIXIEPLATE)
Battle::ItemEffects::DamageCalcFromUser.add(:POISONBARB,
proc { |item, user, target, move, mults, power, type|
mults[:power_multiplier] *= 1.2 if type == :POISON

View File

@@ -183,6 +183,17 @@ EventHandlers.add(:on_step_taken, :auto_move_player,
}
)
# Certain species of Pokémon record the distance travelled while they were in
# the party. Those species use this information to evolve.
EventHandlers.add(:on_step_taken, :party_pokemon_distance_tracker,
proc { |event|
$player.party.each_pokemon do |pkmn|
next if ![:PAWMO, :BRAMBLIN, :RELLOR].include?(pkmn.species)
pkmn.evolution_counter += 1
end
}
)
def pbOnStepTaken(eventTriggered)
if $game_player.move_route_forcing || pbMapInterpreterRunning?
EventHandlers.trigger(:on_step_taken, $game_player)

View File

@@ -15,8 +15,6 @@ class Game_Temp
attr_accessor :encounter_triggered
attr_accessor :encounter_type
attr_accessor :party_levels_before_battle
attr_accessor :party_critical_hits_dealt
attr_accessor :party_direct_damage_taken
def battle_rules
@battle_rules = {} if !@battle_rules
@@ -112,12 +110,8 @@ end
EventHandlers.add(:on_start_battle, :record_party_status,
proc {
$game_temp.party_levels_before_battle = []
$game_temp.party_critical_hits_dealt = []
$game_temp.party_direct_damage_taken = []
$player.party.each_with_index do |pkmn, i|
$game_temp.party_levels_before_battle[i] = pkmn.level
$game_temp.party_critical_hits_dealt[i] = 0
$game_temp.party_direct_damage_taken[i] = 0
end
}
)
@@ -611,8 +605,6 @@ EventHandlers.add(:on_end_battle, :evolve_and_black_out,
pbEvolutionCheck if Settings::CHECK_EVOLUTION_AFTER_ALL_BATTLES ||
(decision != 2 && decision != 5) # not a loss or a draw
$game_temp.party_levels_before_battle = nil
$game_temp.party_critical_hits_dealt = nil
$game_temp.party_direct_damage_taken = nil
# Check for blacking out or gaining Pickup/Huney Gather items
case decision
when 1, 4 # Win, capture
@@ -639,7 +631,7 @@ def pbEvolutionCheck
if new_species.nil? && $game_temp.party_levels_before_battle &&
$game_temp.party_levels_before_battle[i] &&
$game_temp.party_levels_before_battle[i] < pkmn.level
new_species = pkmn.check_evolution_on_level_up
new_species = pkmn.check_evolution_on_battle_level_up
end
new_species = pkmn.check_evolution_after_battle(i) if new_species.nil?
next if new_species.nil?

View File

@@ -715,50 +715,74 @@ ItemHandlers::UseOnPokemonMaximum.add(:HPUP, proc { |item, pkmn|
next pbMaxUsesOfEVRaisingItem(:HP, 10, pkmn, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemonMaximum.copy(:HPUP, :HEALTHMOCHI)
ItemHandlers::UseOnPokemon.add(:HPUP, proc { |item, qty, pkmn, scene|
next pbUseEVRaisingItem(:HP, 10, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemon.copy(:HPUP, :HEALTHMOCHI)
ItemHandlers::UseOnPokemonMaximum.add(:PROTEIN, proc { |item, pkmn|
next pbMaxUsesOfEVRaisingItem(:ATTACK, 10, pkmn, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemonMaximum.copy(:PROTEIN, :MUSCLEMOCHI)
ItemHandlers::UseOnPokemon.add(:PROTEIN, proc { |item, qty, pkmn, scene|
next pbUseEVRaisingItem(:ATTACK, 10, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemon.copy(:PROTEIN, :MUSCLEMOCHI)
ItemHandlers::UseOnPokemonMaximum.add(:IRON, proc { |item, pkmn|
next pbMaxUsesOfEVRaisingItem(:DEFENSE, 10, pkmn, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemonMaximum.copy(:IRON, :RESISTMOCHI)
ItemHandlers::UseOnPokemon.add(:IRON, proc { |item, qty, pkmn, scene|
next pbUseEVRaisingItem(:DEFENSE, 10, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemon.copy(:IRON, :RESISTMOCHI)
ItemHandlers::UseOnPokemonMaximum.add(:CALCIUM, proc { |item, pkmn|
next pbMaxUsesOfEVRaisingItem(:SPECIAL_ATTACK, 10, pkmn, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemonMaximum.copy(:CALCIUM, :GENIUSMOCHI)
ItemHandlers::UseOnPokemon.add(:CALCIUM, proc { |item, qty, pkmn, scene|
next pbUseEVRaisingItem(:SPECIAL_ATTACK, 10, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemon.copy(:CALCIUM, :GENIUSMOCHI)
ItemHandlers::UseOnPokemonMaximum.add(:ZINC, proc { |item, pkmn|
next pbMaxUsesOfEVRaisingItem(:SPECIAL_DEFENSE, 10, pkmn, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemonMaximum.copy(:ZINC, :CLEVERMOCHI)
ItemHandlers::UseOnPokemon.add(:ZINC, proc { |item, qty, pkmn, scene|
next pbUseEVRaisingItem(:SPECIAL_DEFENSE, 10, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemon.copy(:ZINC, :CLEVERMOCHI)
ItemHandlers::UseOnPokemonMaximum.add(:CARBOS, proc { |item, pkmn|
next pbMaxUsesOfEVRaisingItem(:SPEED, 10, pkmn, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemonMaximum.copy(:CARBOS, :SWIFTMOCHI)
ItemHandlers::UseOnPokemon.add(:CARBOS, proc { |item, qty, pkmn, scene|
next pbUseEVRaisingItem(:SPEED, 10, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})
ItemHandlers::UseOnPokemon.copy(:CARBOS, :SWIFTMOCHI)
ItemHandlers::UseOnPokemonMaximum.add(:HEALTHFEATHER, proc { |item, pkmn|
next pbMaxUsesOfEVRaisingItem(:HP, 1, pkmn, true)
})
@@ -831,6 +855,16 @@ ItemHandlers::UseOnPokemon.add(:SWIFTFEATHER, proc { |item, qty, pkmn, scene|
ItemHandlers::UseOnPokemon.copy(:SWIFTFEATHER, :SWIFTWING)
ItemHandlers::UseOnPokemon.add(:FRESHSTARTMOCHI, proc { |item, qty, pkmn, scene|
if !pkmn.ev.any? { |stat, value| value > 0 }
scene.pbDisplay(_INTL("It won't have any effect."))
next false
end
GameData::Stat.each_main { |s| pkmn.ev[s.id] = 0 }
scene.pbDisplay(_INTL("{1}'s base points were all reset to zero!", pkmn.name))
next true
})
ItemHandlers::UseOnPokemon.add(:LONELYMINT, proc { |item, qty, pkmn, scene|
pbNatureChangingMint(:LONELY, item, pkmn, scene)
})
@@ -1198,7 +1232,8 @@ ItemHandlers::UseOnPokemon.add(:PURPLENECTAR, proc { |item, qty, pkmn, scene|
ItemHandlers::UseOnPokemon.add(:REVEALGLASS, proc { |item, qty, pkmn, scene|
if !pkmn.isSpecies?(:TORNADUS) &&
!pkmn.isSpecies?(:THUNDURUS) &&
!pkmn.isSpecies?(:LANDORUS)
!pkmn.isSpecies?(:LANDORUS) &&
!pkmn.isSpecies?(:ENAMORUS)
scene.pbDisplay(_INTL("It had no effect."))
next false
elsif pkmn.fainted?

View File

@@ -149,6 +149,12 @@ MultipleForms.register(:UNOWN, {
}
})
MultipleForms.register(:DUNSPARCE, {
"getFormOnCreation" => proc { |pkmn|
next (rand(100) == 0) ? 1 : 0 # 99% form 0, 1% form 1
}
})
MultipleForms.register(:SPINDA, {
"alterBitmap" => proc { |pkmn, bitmap|
pbSpindaSpots(pkmn, bitmap)
@@ -266,7 +272,7 @@ MultipleForms.register(:ROTOM, {
MultipleForms.register(:GIRATINA, {
"getForm" => proc { |pkmn|
next 1 if pkmn.hasItem?(:GRISEOUSORB)
next 1 if pkmn.hasItem?(:GRISEOUSORB) && Settings::MECHANICS_GENERATION <= 8
next 1 if $game_map&.metadata&.has_flag?("DistortionWorld")
next 0
}
@@ -602,14 +608,14 @@ MultipleForms.register(:TOXEL, {
MultipleForms.copy(:TOXEL, :TOXTRICITY)
MultipleForms.register(:SINISTEA, {
MultipleForms.register(:POLTEAGEIST, {
"getFormOnCreation" => proc { |pkmn|
next 1 if rand(100) < 10 # Antique
next 0 # Phony
}
})
MultipleForms.copy(:SINISTEA, :POLTEAGEIST)
MultipleForms.copy(:POLTEAGEIST, :SINISTEA)
# A Milcery will always have the same flavor, but it is randomly chosen.
MultipleForms.register(:MILCERY, {
@@ -728,34 +734,96 @@ MultipleForms.register(:CALYREX, {
}
})
MultipleForms.register(:LECHONK, {
"getForm" => proc { |pkmn|
next pkmn.gender
}
})
MultipleForms.copy(:LECHONK, :OINKOLOGNE)
MultipleForms.register(:TANDEMAUS, {
"getFormOnCreation" => proc { |pkmn|
next (rand(100) == 0) ? 1 : 0 # 99% form 0, 1% form 1
}
})
MultipleForms.copy(:TANDEMAUS, :MAUSHOLD)
MultipleForms.register(:SQUAWKABILLY, {
"getFormOnCreation" => proc { |pkmn|
next rand(4)
}
})
MultipleForms.register(:TATSUGIRI, {
"getFormOnCreation" => proc { |pkmn|
next rand(3)
}
})
# NOTE: Wild Dudunsparce is always form 0.
# NOTE: Wild Gimmighoul is always form 0.
MultipleForms.register(:POLTCHAGEIST, {
"getFormOnCreation" => proc { |pkmn|
next 1 if rand(100) < 10 # Artisan
next 0 # Counterfeit
}
})
MultipleForms.copy(:POLTCHAGEIST, :SINISCHA)
MultipleForms.register(:OGERPON, {
"getForm" => proc { |pkmn|
next 1 if pkmn.hasItem?(:WELLSPRINGMASK)
next 2 if pkmn.hasItem?(:HEARTHFLAMEMASK)
next 3 if pkmn.hasItem?(:CORNERSTONEMASK)
next 0
}
})
#===============================================================================
# Regional forms
# This code is for determining the form of a Pokémon in an egg created at the
# Day Care, where that Pokémon's species has regional forms. The regional form
# chosen depends on the region in which the egg was produced (not where it
# hatches).
# hatches). The form should have a flag called "EggInRegion_2" where the number
# is the number of the region in which the egg was produced.
#===============================================================================
# The code in this proc assumes that the appropriate regional form for a Pokémon
# is equal to the region's number. This may not be true in your game.
# Note that this proc only produces a non-zero form number if the species has a
# defined form with that number, which means it can be used for both Alolan and
# Galarian forms separately (and for Meowth which has both).
MultipleForms.register(:RATTATA, {
"getFormOnEggCreation" => proc { |pkmn|
if $game_map
map_pos = $game_map.metadata&.town_map_position
next map_pos[0] if map_pos &&
GameData::Species.get_species_form(pkmn.species, map_pos[0]).form == map_pos[0]
region_num = map_pos[0]
found_form = -1
GameData::Species.each_form_for_species(pkmn.species) do |sp_data|
sp_data.flags.each do |flag|
if flag[/^EggInRegion_(\d+)$/i] && $~[1].to_i == region_num
found_form = sp_data.form
break
end
end
break if found_form >= 0
end
next found_form if found_form >= 0
end
next 0
}
})
MultipleForms.copy(:RATTATA, :SANDSHREW, :VULPIX, :DIGLETT, :MEOWTH, :GEODUDE,
:GRIMER, :PONYTA, :FARFETCHD, :CORSOLA, :ZIGZAGOON,
:DARUMAKA, :YAMASK, :STUNFISK, :SLOWPOKE, :ARTICUNO, :ZAPDOS,
:MOLTRES)
MultipleForms.copy(
# Alolan forms
:RATTATA, :SANDSHREW, :VULPIX, :DIGLETT, :MEOWTH, :GEODUDE, :GRIMER,
# Galarian forms (excluding Meowth which is above)
:PONYTA, :SLOWPOKE, :FARFETCHD, :ARTICUNO, :ZAPDOS, :MOLTRES, :CORSOLA,
:ZIGZAGOON, :DARUMAKA, :YAMASK, :STUNFISK,
# Hisuian forms
:GROWLITHE, :VOLTORB, :QWILFISH, :SNEASEL, :ZORUA,
# Paldean forms
:TAUROS, :WOOPER
)
#===============================================================================
# Regional forms
@@ -790,3 +858,21 @@ MultipleForms.register(:KOFFING, {
})
MultipleForms.copy(:KOFFING, :MIMEJR)
# Hisuian forms
MultipleForms.register(:QUILAVA, {
"getForm" => proc { |pkmn|
next if pkmn.form_simple >= 2
if $game_map
map_pos = $game_map.metadata&.town_map_position
next 1 if map_pos && map_pos[0] == 3 # Hisui region
end
next 0
}
})
MultipleForms.copy(:QUILAVA,
:DEWOTT, :PETILILL, :RUFFLET, :GOOMY, :BERGMITE, :DARTRIX)
# Paldean forms
# None!

View File

@@ -360,6 +360,9 @@ class Battle::Move::UserLosesHalfHP < Battle::Move::RecoilMove
# NOTE: This move's recoil is not prevented by Rock Head/Magic Guard.
amt = pbRecoilDamage(user, target)
amt = 1 if amt < 1
if user.pokemon.isSpecies?(:BASCULIN) && [2, 3].include?(user.pokemon.form)
user.pokemon.evolution_counter += amt
end
user.pbReduceHP(amt, false)
@battle.pbDisplay(_INTL("{1} is damaged by recoil!", user.pbThis))
user.pbItemHPHealCheck

View File

@@ -252,8 +252,10 @@ class Pokemon
# @param value [Integer] new HP value
def hp=(value)
@hp = value.clamp(0, @totalhp)
heal_status if @hp == 0
@ready_to_evolve = false if @hp == 0
return if @hp > 0
heal_status
@ready_to_evolve = false
@evolution_counter = 0 if isSpecies?(:BASCULIN) || isSpecies?(:YAMASK)
end
# Sets this Pokémon's status. See {GameData::Status} for all possible status effects.
@@ -988,6 +990,16 @@ class Pokemon
end
end
# Checks whether this Pokemon can evolve because of levelling up in battle.
# This also checks call_level_up as above.
# @return [Symbol, nil] the ID of the species to evolve into
def check_evolution_on_battle_level_up
return check_evolution_internal do |pkmn, new_species, method, parameter|
success = GameData::Evolution.get(method).call_battle_level_up(pkmn, parameter)
next (success) ? new_species : nil
end
end
# Checks whether this Pokemon can evolve because of using an item on it.
# @param item_used [Symbol, GameData::Item, nil] the item being used
# @return [Symbol, nil] the ID of the species to evolve into

View File

@@ -136,24 +136,21 @@ module Compiler
yield lastsection, sectionname if havesection
end
# Used for types.txt, abilities.txt, moves.txt, items.txt, berry_plants.txt,
# pokemon.txt, pokemon_forms.txt, pokemon_metrics.txt, shadow_pokemon.txt,
# ribbons.txt, trainer_types.txt, battle_facility_lists.txt, Battle Tower
# trainers PBS files and dungeon_parameters.txt
# Used for most PBS files.
def pbEachFileSection(f, schema = nil)
pbEachFileSectionEx(f, schema) do |section, name|
yield section, name if block_given? && name[/^.+$/]
end
end
# Used for metadata.txt and map_metadata.txt
# Unused.
def pbEachFileSectionNumbered(f, schema = nil)
pbEachFileSectionEx(f, schema) do |section, name|
yield section, name.to_i if block_given? && name[/^\d+$/]
end
end
# Used by translated text compiler
# Used by translated text compiler.
def pbEachSection(f)
lineno = 1
havesection = false
@@ -183,7 +180,7 @@ module Compiler
yield lastsection, sectionname if havesection
end
# Unused
# Unused.
def pbEachCommentedLine(f)
lineno = 1
f.each_line do |line|
@@ -196,7 +193,7 @@ module Compiler
end
end
# Used for town_map.txt and Battle Tower Pokémon PBS files
# Used for Battle Tower Pokémon PBS files.
def pbCompilerEachCommentedLine(filename)
File.open(filename, "rb") do |f|
FileLineData.file = filename
@@ -215,7 +212,7 @@ module Compiler
end
end
# Unused
# Unused.
def pbEachPreppedLine(f)
lineno = 1
f.each_line do |line|
@@ -229,8 +226,8 @@ module Compiler
end
end
# Used for map_connections.txt, phone.txt, regional_dexes.txt, encounters.txt,
# trainers.txt and dungeon_tilesets.txt
# Used for map_connections.txt, regional_dexes.txt, encounters.txt,
# trainers.txt and plugin meta.txt files.
def pbCompilerEachPreppedLine(filename)
File.open(filename, "rb") do |f|
FileLineData.file = filename
@@ -986,7 +983,7 @@ module Compiler
e = $!
raise e if e.class.to_s == "Reset" || e.is_a?(Reset) || e.is_a?(SystemExit)
pbPrintException(e)
data_files.each do |filename|
get_all_pbs_data_filenames_to_compile.each do |filename|
begin
File.delete("Data/#{filename[0]}") if FileTest.exist?("Data/#{filename[0]}")
rescue SystemCallError

View File

@@ -981,7 +981,7 @@ module Compiler
end
elsif sub_schema[key] # Property of a Pokémon
if !current_pkmn
raise _INTL("Pokémon hasn't been defined yet!") + "\n" + FileLineData.linereport
raise _INTL("Property \"{1}\" is Pokémon-specific, but a Pokémon hasn't been defined yet.", key) + "\n" + FileLineData.linereport
end
current_pkmn[sub_schema[key][0]] = get_csv_record($~[2], sub_schema[key])
end