Files
infinitefusion-e18/Data/Scripts/053_PIF_Hoenn/TrainerRematches/TrainerRematch_RandomEvents.rb
T
2026-07-10 15:42:06 -04:00

234 lines
8.5 KiB
Ruby

# frozen_string_literal: true
def printNPCTrainerCurrentTeam(trainer)
team_string = "["
trainer.currentTeam.each do |pokemon|
name= get_pokemon_readable_internal_name(pokemon)
level = pokemon.level
formatted_info = "#{name} (lv.#{level}), "
team_string += formatted_info
end
team_string += "]"
echoln "Trainer's current team is: #{team_string}"
end
def applyTrainerRandomEvents(trainer,event_type=nil)
if trainer.has_pending_action
echoln "Trainer has pending action"
end
return trainer if trainer.has_pending_action
trainer.clear_previous_random_events
#time_passed = trainer.getTimeSinceLastAction
#return trainer if time_passed < TIME_FOR_RANDOM_EVENTS
catch_chance_for_number_in_team = [100,40,30,20,10,5,0]
unfuse_chance_for_number_in_team = [0,10,10,5,5,0,0]
fuse_chance_for_number_in_team = [0,0,40,60,65,75,85]
#Odds of certain events depends on nb. of pokemon in current party
catch_chance = catch_chance_for_number_in_team[trainer.currentTeam.length]
unfuse_chance = unfuse_chance_for_number_in_team[trainer.currentTeam.length]
fuse_chance = fuse_chance_for_number_in_team[trainer.currentTeam.length]
# Chances out of 100
weighted_events = [
[:CATCH, catch_chance], #Depends on nb of pokemon in team. 40% if only 1, then DECREASES with the nb.
[:FUSE, fuse_chance], #Depends on nb of pokemon in team. 40% if 2, then INCREASES with the nb.
[:REVERSE, 10],
[:UNFUSE, unfuse_chance] #Depends on nb of pokemon in team. 10% if 1 or 2, 5% if 3 or 4. .
]
event_pool = weighted_events.flat_map { |event, weight| [event] * weight }
selected_event = event_pool.sample
selected_event = event_type if event_type
#Random event guaranteed after 1st rematch only (can still fail if they don't have the requirements tho)
if selected_event.nil? && trainer.nb_rematches == 1
selected_event = event_pool.sample until selected_event
end
if selected_event
echoln "Trying to do random event: #{selected_event}"
end
return trainer if selected_event.nil?
original_team = trainer.currentTeam.clone
case selected_event
when :CATCH
trainer = catch_new_team_pokemon(trainer)
when :FUSE
trainer = fuse_random_team_pokemon(trainer)
when :UNFUSE
trainer = unfuse_random_team_pokemon(trainer)
when :REVERSE
trainer = reverse_random_team_pokemon(trainer)
end
new_team = trainer.currentTeam
team_changed = original_team != new_team
trainer.set_pending_action(team_changed)
printNPCTrainerCurrentTeam(trainer)
return trainer
end
def chooseEncounterType(trainerClass)
water_trainer_classes = [:SWIMMER_F, :SWIMMER_M,:SWIMMER2_M,:SWIMMER2_F, :FISHERMAN, :SURFER, :DIVER_M, :DIVER_F]
hybrid_trainer_classes = [:COOLTRAINER_M, :COOLTRAINER_F, :TRIATHLETE_SWIM_M, :TRIATHLETE_SWIM_F,
:TRIATHLETE_RUN_M, :TRIATHLETE_RUN_F, :SAILOR, :TUBER_M, :TUBER_F]
if water_trainer_classes.include?(trainerClass )
chance_of_land_encounter = 0
chance_of_surf_encounter= 5
chance_of_cave_encounter = 0
chance_of_fishing_encounter = 5
elsif hybrid_trainer_classes.include?(trainerClass )
chance_of_land_encounter = 5
chance_of_surf_encounter= 2
chance_of_cave_encounter = 5
chance_of_fishing_encounter = 2
else
chance_of_land_encounter = 5
chance_of_surf_encounter= 0
chance_of_cave_encounter = 5
chance_of_fishing_encounter = 0
end
$PokemonEncounters.has_water_encounters?
possible_encounter_types = []
if $PokemonEncounters.has_land_encounters?
possible_encounter_types += [:Land] * chance_of_land_encounter
end
if $PokemonEncounters.has_cave_encounters?
possible_encounter_types += [:Cave] * chance_of_cave_encounter
end
if $PokemonEncounters.has_water_encounters?
possible_encounter_types += [:GoodRod] * chance_of_fishing_encounter
possible_encounter_types += [:Water] * chance_of_surf_encounter
end
return getTimeBasedEncounter(possible_encounter_types.sample)
end
def getTimeBasedEncounter(encounter_type)
time = pbGetTimeNow
return $PokemonEncounters.find_valid_encounter_type_for_time(encounter_type, time)
end
def catch_new_team_pokemon(trainer)
return trainer if trainer.currentTeam.length >= 6
encounter_type = chooseEncounterType(trainer.trainerType)
return trainer if !encounter_type
echoln "Catching a pokemon via encounter_type #{encounter_type}"
# 3 rolls for favorite type, then normal roll
wild_pokemon = select_npc_new_pokemon(encounter_type, trainer.favorite_type)
if wild_pokemon
trainer_highest_level = get_trainer_highest_level(trainer)
species = wild_pokemon[0]
level = [wild_pokemon[1], trainer_highest_level].min
original_trainer =pbLoadTrainer(trainer.trainerType,trainer.trainerName,0)
trainer.currentTeam << Pokemon.new(species,level,original_trainer)
trainer.log_catch_event(wild_pokemon[0])
end
return trainer
end
# 3 rolls for favorite type, then normal roll
def select_npc_new_pokemon(encounter_type, favorite_type)
(1..3).each { |i|
wild_pokemon = $PokemonEncounters.choose_wild_pokemon(encounter_type)
next unless wild_pokemon
species = wild_pokemon[0]
if GameData::Species.get(species)&.hasType?(favorite_type)
return wild_pokemon
end
}
return $PokemonEncounters.choose_wild_pokemon(encounter_type)
end
def get_trainer_highest_level(trainer)
highest_level = 1
trainer.currentTeam.each do |pokemon|
highest_level = pokemon.level if pokemon.level > highest_level
end
return highest_level
end
def reverse_random_team_pokemon(trainer)
eligible_pokemon = trainer.list_team_fused_pokemon
return trainer if eligible_pokemon.length < 1
return trainer if trainer.currentTeam.length > 5
pokemon_to_reverse = eligible_pokemon.sample
old_species = pokemon_to_reverse.species
trainer.currentTeam.delete(pokemon_to_reverse)
body_pokemon = get_body_species_from_symbol(pokemon_to_reverse.species)
head_pokemon = get_head_species_from_symbol(pokemon_to_reverse.species)
pokemon_to_reverse.species = getFusedPokemonIdFromSymbols(head_pokemon,body_pokemon)
pokemon_to_reverse.pif_sprite=nil
trainer.currentTeam.push(pokemon_to_reverse)
trainer.log_reverse_event(old_species,pokemon_to_reverse.species)
return trainer
end
def unfuse_random_team_pokemon(trainer)
eligible_pokemon = trainer.list_team_fused_pokemon
return trainer if eligible_pokemon.length < 1
return trainer if trainer.currentTeam.length > 5
pokemon_to_unfuse = eligible_pokemon.sample
return trainer if pokemon_to_unfuse.owner.name != trainer.trainerName
body_pokemon = get_body_id_from_symbol(pokemon_to_unfuse.species)
head_pokemon = get_head_id_from_symbol(pokemon_to_unfuse.species)
level = calculateUnfuseLevelOldMethod(pokemon_to_unfuse,false)
if pokemon_to_unfuse.item
trainer.inventory << pokemon_to_unfuse.item.id
end
trainer.currentTeam.delete(pokemon_to_unfuse)
original_trainer =pbLoadTrainer(trainer.trainerType,trainer.trainerName,0)
trainer.currentTeam.push(Pokemon.new(body_pokemon,level,original_trainer))
trainer.currentTeam.push(Pokemon.new(head_pokemon,level,original_trainer))
trainer.log_unfusion_event(pokemon_to_unfuse.species, body_pokemon, head_pokemon)
return trainer
end
def fuse_random_team_pokemon(trainer)
eligible_pokemon = trainer.list_team_unfused_pokemon
return trainer if eligible_pokemon.length < 2
pokemon_to_fuse = eligible_pokemon.sample(2)
body_pokemon = pokemon_to_fuse[0]
head_pokemon = pokemon_to_fuse[1]
fusion_species = getFusedPokemonIdFromSymbols(body_pokemon.species,head_pokemon.species)
level = (body_pokemon.level + head_pokemon.level)/2
original_trainer =pbLoadTrainer(trainer.trainerType,trainer.trainerName,0)
fused_pokemon = Pokemon.new(fusion_species,level,original_trainer)
trainer.currentTeam.delete(body_pokemon)
trainer.currentTeam.delete(head_pokemon)
trainer.currentTeam.push(fused_pokemon)
trainer.log_fusion_event(body_pokemon.species,head_pokemon.species,fusion_species)
return trainer
end
def getBestMatchingPreviousRandomEvent(trainer_data, previous_events)
return nil if trainer_data.nil? || previous_events.nil?
priority = [:CATCH, :EVOLVE, :FUSE, :UNFUSE, :REVERSE]
event_message_map = {
CATCH: trainer_data.preRematchText_caught,
EVOLVE: trainer_data.preRematchText_evolved,
FUSE: trainer_data.preRematchText_fused,
UNFUSE: trainer_data.preRematchText_unfused,
REVERSE: trainer_data.preRematchText_reversed
}
sorted_events = previous_events.sort_by do |event|
priority.index(event.eventType) || Float::INFINITY
end
sorted_events.find { |event| event_message_map[event.eventType] }
end