Converted Shadow Pokémon PBS file to a section-based format, improved Shadow Pokémon mechanics

This commit is contained in:
Maruno17
2021-11-21 00:44:41 +00:00
parent 048a18b415
commit b445f26a88
25 changed files with 761 additions and 204 deletions

View File

@@ -187,9 +187,7 @@ class Battle::Battler
def pbInitPokemon(*arg)
if self.pokemonIndex>0 && inHyperMode?
# Called out of Hyper Mode
self.pokemon.hyper_mode = false
self.pokemon.adjustHeart(-50)
end
__shadow__pbInitPokemon(*arg)
# Called into battle
@@ -198,7 +196,7 @@ class Battle::Battler
self.type1 = :SHADOW
self.type2 = :SHADOW
end
self.pokemon.adjustHeart(-30) if pbOwnedByPlayer?
self.pokemon.change_heart_gauge("battle") if pbOwnedByPlayer?
end
end
@@ -216,7 +214,7 @@ class Battle::Battler
def pbHyperMode
return if fainted? || !shadowPokemon? || inHyperMode? || !pbOwnedByPlayer?
p = self.pokemon
if @battle.pbRandom(p.heart_gauge) <= Pokemon::HEART_GAUGE_SIZE / 4
if @battle.pbRandom(p.heart_gauge) <= p.max_gauge_size / 4
p.hyper_mode = true
@battle.pbDisplay(_INTL("{1}'s emotions rose to a fever pitch!\nIt entered Hyper Mode!",self.pbThis))
end
@@ -234,39 +232,37 @@ end
#===============================================================================
# Shadow item effects.
#===============================================================================
def pbRaiseHappinessAndReduceHeart(pkmn, scene, heart_amount)
def pbRaiseHappinessAndReduceHeart(pkmn, scene, multiplier)
if !pkmn.shadowPokemon? || (pkmn.happiness == 255 && pkmn.heart_gauge == 0)
scene.pbDisplay(_INTL("It won't have any effect."))
return false
end
if pkmn.happiness == 255
stage = pkmn.heart_gauge
pkmn.adjustHeart(-heart_amount)
scene.pbDisplay(_INTL("{1} adores you!\nThe door to its heart opened a little.", pkmn.name))
pkmn.check_ready_to_purify if pkmn.heart_gauge != stage
elsif pkmn.heart_gauge == 0
pkmn.changeHappiness("vitamin")
old_gauge = pkmn.heart_gauge
old_happiness = pkmn.happiness
pkmn.changeHappiness("vitamin")
pkmn.change_heart_gauge("scent", multiplier)
if pkmn.heart_gauge == old_gauge
scene.pbDisplay(_INTL("{1} turned friendly.", pkmn.name))
elsif pkmn.happiness == old_happiness
scene.pbDisplay(_INTL("{1} adores you!\nThe door to its heart opened a little.", pkmn.name))
pkmn.check_ready_to_purify
else
stage = pkmn.heart_gauge
pkmn.changeHappiness("vitamin")
pkmn.adjustHeart(-heart_amount)
scene.pbDisplay(_INTL("{1} turned friendly.\nThe door to its heart opened a little.", pkmn.name))
pkmn.check_ready_to_purify if pkmn.heart_gauge != stage
pkmn.check_ready_to_purify
end
return true
end
ItemHandlers::UseOnPokemon.add(:JOYSCENT,proc { |item,pokemon,scene|
pbRaiseHappinessAndReduceHeart(pokemon,scene,500)
pbRaiseHappinessAndReduceHeart(pokemon, scene, 1)
})
ItemHandlers::UseOnPokemon.add(:EXCITESCENT,proc { |item,pokemon,scene|
pbRaiseHappinessAndReduceHeart(pokemon,scene,1000)
pbRaiseHappinessAndReduceHeart(pokemon, scene, 2)
})
ItemHandlers::UseOnPokemon.add(:VIVIDSCENT,proc { |item,pokemon,scene|
pbRaiseHappinessAndReduceHeart(pokemon,scene,2000)
pbRaiseHappinessAndReduceHeart(pokemon, scene, 3)
})
ItemHandlers::UseOnPokemon.add(:TIMEFLUTE,proc { |item,pokemon,scene|
@@ -291,21 +287,21 @@ ItemHandlers::CanUseInBattle.copy(:JOYSCENT,:EXCITESCENT,:VIVIDSCENT)
ItemHandlers::BattleUseOnBattler.add(:JOYSCENT,proc { |item,battler,scene|
battler.pokemon.hyper_mode = false
battler.pokemon.adjustHeart(-100)
battler.pokemon.change_heart_gauge("scent", 1)
scene.pbDisplay(_INTL("{1} came to its senses from the {2}!",battler.pbThis,GameData::Item.get(item).name))
next true
})
ItemHandlers::BattleUseOnBattler.add(:EXCITESCENT,proc { |item,battler,scene|
battler.pokemon.hyper_mode = false
battler.pokemon.adjustHeart(-200)
battler.pokemon.change_heart_gauge("scent", 2)
scene.pbDisplay(_INTL("{1} came to its senses from the {2}!",battler.pbThis,GameData::Item.get(item).name))
next true
})
ItemHandlers::BattleUseOnBattler.add(:VIVIDSCENT,proc { |item,battler,scene|
battler.pokemon.hyper_mode = false
battler.pokemon.adjustHeart(-300)
battler.pokemon.change_heart_gauge("scent", 3)
scene.pbDisplay(_INTL("{1} came to its senses from the {2}!",battler.pbThis,GameData::Item.get(item).name))
next true
})
@@ -416,25 +412,23 @@ Events.onEndBattle += proc { |_sender,_e|
}
Events.onStepTaken += proc {
for pkmn in $player.able_party
$player.able_party.each do |pkmn|
next if pkmn.heart_gauge == 0
stage = pkmn.heartStage
pkmn.adjustHeart(-1)
case pkmn.heartStage
when 0
pkmn.check_ready_to_purify
when stage
else
pkmn.update_shadow_moves
pkmn.heart_gauge_step_counter = 0 if !pkmn.heart_gauge_step_counter
pkmn.heart_gauge_step_counter += 1
if pkmn.heart_gauge_step_counter >= 256
old_stage = pkmn.heartStage
pkmn.change_heart_gauge("walking")
new_stage = pkmn.heartStage
if new_stage == 0
pkmn.check_ready_to_purify
elsif new_stage != old_stage
pkmn.update_shadow_moves
end
pkmn.heart_gauge_step_counter = 0
end
end
if ($PokemonGlobal.purifyChamber rescue nil)
$PokemonGlobal.purifyChamber.update
end
$PokemonGlobal.day_care.slots.each do |slot|
next if !slot.filled? || !slot.pokemon.shadowPokemon?
old_stage = slot.pokemon.heartStage
slot.pokemon.adjustHeart(-1)
slot.pokemon.update_shadow_moves if slot.pokemon.heartStage != old_stage
end
}

View File

@@ -8,7 +8,7 @@ class Pokemon
attr_accessor :saved_exp
attr_accessor :saved_ev
attr_accessor :shadow_moves
HEART_GAUGE_SIZE = 3840
attr_accessor :heart_gauge_step_counter
alias :__shadow_expeq :exp=
def exp=(value)
@@ -29,15 +29,74 @@ class Pokemon
return @heart_gauge || 0
end
def shadow_data
ret = GameData::ShadowPokemon.try_get(species_data.id)
ret = GameData::ShadowPokemon.try_get(@species) if !ret
return ret
end
def max_gauge_size
data = shadow_data
return (data) ? data.gauge_size : GameData::ShadowPokemon::HEART_GAUGE_SIZE
end
def adjustHeart(value)
return if !shadowPokemon?
@heart_gauge = (self.heart_gauge + value).clamp(0, HEART_GAUGE_SIZE)
@heart_gauge = (self.heart_gauge + value).clamp(0, max_gauge_size)
end
def change_heart_gauge(method, multiplier = 1)
return if !shadowPokemon?
heart_amounts = {
# [sending into battle, call to, walking 256 steps, using scent]
:HARDY => [110, 300, 100, 90],
:LONELY => [ 70, 330, 100, 130],
:BRAVE => [130, 270, 90, 80],
:ADAMANT => [110, 270, 110, 80],
:NAUGHTY => [120, 270, 110, 70],
:BOLD => [110, 270, 90, 100],
:DOCILE => [100, 360, 80, 120],
:RELAXED => [ 90, 270, 110, 100],
:IMPISH => [120, 300, 100, 80],
:LAX => [100, 270, 90, 110],
:TIMID => [ 70, 330, 110, 120],
:HASTY => [130, 300, 70, 100],
:SERIOUS => [100, 330, 110, 90],
:JOLLY => [120, 300, 90, 90],
:NAIVE => [100, 300, 120, 80],
:MODEST => [ 70, 300, 120, 110],
:MILD => [ 80, 270, 100, 120],
:QUIET => [100, 300, 100, 100],
:BASHFUL => [ 80, 300, 90, 130],
:RASH => [ 90, 300, 90, 120],
:CALM => [ 80, 300, 110, 110],
:GENTLE => [ 70, 300, 130, 100],
:SASSY => [130, 240, 100, 70],
:CAREFUL => [ 90, 300, 100, 110],
:QUIRKY => [130, 270, 80, 90]
}
amt = 100
case method
when "battle"
amt = (heart_amounts[@nature]) ? heart_amounts[@nature][0] : 100
when "call"
amt = (heart_amounts[@nature]) ? heart_amounts[@nature][1] : 300
when "walking"
amt = (heart_amounts[@nature]) ? heart_amounts[@nature][2] : 100
when "scent"
amt = (heart_amounts[@nature]) ? heart_amounts[@nature][3] : 100
amt *= multiplier
else
raise _INTL("Unknown heart gauge-changing method: {1}", method.to_s)
end
adjustHeart(-amt)
end
def heartStage
return 0 if !shadowPokemon?
stage_size = HEART_GAUGE_SIZE / 5.0
return ([self.heart_gauge, HEART_GAUGE_SIZE].min / stage_size).ceil
max_size = max_gauge_size
stage_size = max_size / 5.0
return ([self.heart_gauge, max_size].min / stage_size).ceil
end
def shadowPokemon?
@@ -48,36 +107,42 @@ class Pokemon
return (self.heart_gauge == 0 || @hp == 0) ? false : @hyper_mode
end
alias __shadow__changeHappiness changeHappiness
def changeHappiness(method)
return if shadowPokemon? && heartStage >= 4
__shadow__changeHappiness(method)
end
def makeShadow
@shadow = true
@heart_gauge = HEART_GAUGE_SIZE
@hyper_mode = false
@saved_exp = 0
@saved_ev = {}
GameData::Stat.each_main { |s| @saved_ev[s.id] = 0 }
@heart_gauge = max_gauge_size
@heart_gauge_step_counter = 0
@shadow_moves = []
# Retrieve Shadow moveset for this Pokémon
shadow_moveset = pbLoadShadowMovesets[species_data.id]
shadow_moveset = pbLoadShadowMovesets[@species] if !shadow_moveset || shadow_moveset.length == 0
data = shadow_data
# Record this Pokémon's Shadow moves
if shadow_moveset && shadow_moveset.length > 0
for i in 0...[shadow_moveset.length, MAX_MOVES].min
@shadow_moves[i] = shadow_moveset[i]
if data
data.moves.each do |m|
@shadow_moves.push(m.to_sym) if GameData::Move.exists?(m.to_sym)
break if @shadow_moves.length >= MAX_MOVES
end
elsif GameData::Move.exists?(:SHADOWRUSH)
# No Shadow moveset defined; just use Shadow Rush
@shadow_moves[0] = :SHADOWRUSH
else
raise _INTL("Expected Shadow moves or Shadow Rush to be defined, but they weren't.")
end
if @shadow_moves.empty? && GameData::Move.exists?(:SHADOWRUSH)
@shadow_moves.push(:SHADOWRUSH)
end
# Record this Pokémon's original moves
@moves.each_with_index { |m, i| @shadow_moves[MAX_MOVES + i] = m.id }
# Update moves
update_shadow_moves
if !@shadow_moves.empty?
@moves.each_with_index { |m, i| @shadow_moves[MAX_MOVES + i] = m.id }
update_shadow_moves
end
end
def update_shadow_moves(relearn_all_moves = false)
return if !@shadow_moves
return if !@shadow_moves || @shadow_moves.empty?
# Not a Shadow Pokémon (any more); relearn all its original moves
if !shadowPokemon?
if @shadow_moves.length > MAX_MOVES