mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-12 07:35:00 +00:00
6.6 update
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
|
||||
TRAINER_CLASS_FAVORITE_TYPES =
|
||||
{
|
||||
AROMALADY: [:GRASS, :FAIRY],
|
||||
BEAUTY: [:FAIRY, :WATER, :NORMAL, :GRASS],
|
||||
BIKER: [:POISON, :DARK],
|
||||
BIRDKEEPER: [:FLYING, :NORMAL],
|
||||
BUGCATCHER: [:BUG],
|
||||
BURGLAR: [:FIRE, :DARK],
|
||||
CHANNELER: [:GHOST, :PSYCHIC],
|
||||
CUEBALL: [:FIGHTING, :STEEL],
|
||||
ENGINEER: [:ELECTRIC, :STEEL],
|
||||
FISHERMAN: [:WATER],
|
||||
GAMBLER: [:NORMAL, :PSYCHIC],
|
||||
GENTLEMAN: [:NORMAL, :STEEL],
|
||||
HIKER: [:ROCK, :GROUND],
|
||||
JUGGLER: [:PSYCHIC, :GHOST, :NORMAL, :POISON],
|
||||
LADY: [:FAIRY, :NORMAL],
|
||||
PAINTER: [:NORMAL, :PSYCHIC, :GRASS],
|
||||
POKEMANIAC: [:DRAGON, :GROUND],
|
||||
POKEMONBREEDER: [:NORMAL, :GRASS],
|
||||
PROFESSOR: [:NORMAL, :PSYCHIC],
|
||||
ROCKER: [:ELECTRIC, :FIRE],
|
||||
RUINMANIAC: [:GROUND, :ROCK, :PSYCHIC],
|
||||
SAILOR: [:WATER, :FIGHTING],
|
||||
SCIENTIST: [:ELECTRIC, :STEEL, :POISON],
|
||||
SUPERNERD: [:ELECTRIC, :PSYCHIC, :STEEL],
|
||||
TAMER: [:NORMAL, :DARK],
|
||||
BLACKBELT: [:FIGHTING],
|
||||
CRUSHGIRL: [:FIGHTING],
|
||||
CAMPER: [:BUG, :NORMAL, :GRASS],
|
||||
PICNICKER: [:GRASS, :NORMAL],
|
||||
COOLTRAINER_M: [:DRAGON, :STEEL, :FIRE],
|
||||
COOLTRAINER_F: [:ICE, :PSYCHIC, :FAIRY],
|
||||
YOUNGSTER: [:NORMAL, :BUG, :GRASS, :FLYING],
|
||||
LASS: [:NORMAL, :FAIRY],
|
||||
POKEMONRANGER_M: [:GRASS, :GROUND],
|
||||
POKEMONRANGER_F: [:GRASS, :WATER],
|
||||
PSYCHIC_M: [:PSYCHIC, :GHOST],
|
||||
PSYCHIC_F: [:PSYCHIC, :FAIRY],
|
||||
SWIMMER_M: [:WATER, :ICE],
|
||||
SWIMMER_F: [:WATER, :ICE],
|
||||
SWIMMER2_M: [:WATER],
|
||||
SWIMMER2_F: [:WATER],
|
||||
TUBER_M: [:WATER],
|
||||
TUBER_F: [:WATER],
|
||||
TUBER2_M: [:WATER],
|
||||
TUBER2_F: [:WATER],
|
||||
COOLCOUPLE: [:FIRE, :ICE],
|
||||
CRUSHKIN: [:FIGHTING],
|
||||
SISANDBRO: [:WATER, :GROUND],
|
||||
TWINS: [:FAIRY, :NORMAL],
|
||||
YOUNGCOUPLE: [:NORMAL, :PSYCHIC],
|
||||
SOCIALITE: [:FAIRY, :NORMAL],
|
||||
BUGCATCHER_F: [:BUG],
|
||||
ROUGHNECK: [:DARK, :FIGHTING],
|
||||
TEACHER: [:PSYCHIC, :NORMAL],
|
||||
PRESCHOOLER_M: [:NORMAL, :BUG],
|
||||
PRESCHOOLER_F: [:FAIRY, :NORMAL],
|
||||
HAUNTEDGIRL_YOUNG: [:GHOST],
|
||||
HAUNTEDGIRL: [:GHOST, :DARK],
|
||||
CLOWN: [:PSYCHIC, :FAIRY],
|
||||
NURSE: [:NORMAL, :FAIRY],
|
||||
WORKER: [:STEEL, :GROUND],
|
||||
COOLTRAINER_M2: [:FIGHTING, :STEEL],
|
||||
COOLTRAINER_F2: [:PSYCHIC, :ICE],
|
||||
FARMER: [:GRASS, :GROUND, :NORMAL],
|
||||
PYROMANIAC: [:FIRE],
|
||||
KIMONOGIRL: [:FAIRY, :PSYCHIC, :GHOST],
|
||||
SAGE: [:PSYCHIC, :GHOST],
|
||||
PLAYER: [:ICE, :FIGHTING],
|
||||
POLICE: [:DARK, :FIGHTING],
|
||||
SKIER_F: [:ICE],
|
||||
DELIVERYMAN: [:NORMAL],
|
||||
}
|
||||
|
||||
#Higher values: pickier
|
||||
TRAINER_CLASS_PICKINESS = {
|
||||
AROMALADY: 1.8,
|
||||
BEAUTY: 2.2,
|
||||
BIKER: 1.2,
|
||||
BIRDKEEPER: 1.4,
|
||||
BUGCATCHER: 1.1,
|
||||
BURGLAR: 1.3,
|
||||
CHANNELER: 1.7,
|
||||
CUEBALL: 1.3,
|
||||
ENGINEER: 2.0,
|
||||
FISHERMAN: 1.4,
|
||||
GAMBLER: 1.5,
|
||||
GENTLEMAN: 2.3,
|
||||
HIKER: 1.5,
|
||||
JUGGLER: 1.8,
|
||||
LADY: 2.4,
|
||||
PAINTER: 2.0,
|
||||
POKEMANIAC: 1.6,
|
||||
POKEMONBREEDER: 1.9,
|
||||
PROFESSOR: 2.5,
|
||||
ROCKER: 1.4,
|
||||
RUINMANIAC: 1.5,
|
||||
SAILOR: 1.3,
|
||||
SCIENTIST: 2.0,
|
||||
SUPERNERD: 1.9,
|
||||
TAMER: 1.5,
|
||||
BLACKBELT: 1.7,
|
||||
CRUSHGIRL: 1.6,
|
||||
CAMPER: 1.2,
|
||||
PICNICKER: 1.2,
|
||||
COOLTRAINER_M: 2.4,
|
||||
COOLTRAINER_F: 2.4,
|
||||
YOUNGSTER: 0.9,
|
||||
LASS: 1.0,
|
||||
POKEMONRANGER_M: 2.0,
|
||||
POKEMONRANGER_F: 2.0,
|
||||
PSYCHIC_M: 2.0,
|
||||
PSYCHIC_F: 2.0,
|
||||
SWIMMER_M: 1.0,
|
||||
SWIMMER_F: 1.0,
|
||||
SWIMMER2_M: 1.0,
|
||||
SWIMMER2_F: 1.0,
|
||||
TUBER_M: 0.8,
|
||||
TUBER_F: 0.8,
|
||||
TUBER2_M: 0.8,
|
||||
TUBER2_F: 0.8,
|
||||
COOLCOUPLE: 2.1,
|
||||
CRUSHKIN: 1.7,
|
||||
SISANDBRO: 1.3,
|
||||
TWINS: 1.0,
|
||||
YOUNGCOUPLE: 1.6,
|
||||
SOCIALITE: 2.3,
|
||||
BUGCATCHER_F: 1.1,
|
||||
ROUGHNECK: 1.4,
|
||||
TEACHER: 2.0,
|
||||
PRESCHOOLER_M: 0.6,
|
||||
PRESCHOOLER_F: 0.6,
|
||||
HAUNTEDGIRL_YOUNG: 1.3,
|
||||
HAUNTEDGIRL: 1.7,
|
||||
CLOWN: 1.5,
|
||||
NURSE: 2.0,
|
||||
WORKER: 1.6,
|
||||
COOLTRAINER_M2: 2.4,
|
||||
COOLTRAINER_F2: 2.4,
|
||||
FARMER: 1.5,
|
||||
PYROMANIAC: 1.6,
|
||||
KIMONOGIRL: 2.2,
|
||||
SAGE: 2.1,
|
||||
PLAYER: 1.0,
|
||||
POLICE: 1.8,
|
||||
SKIER_F: 1.6,
|
||||
DELIVERYMAN: 1.3
|
||||
}
|
||||
|
||||
|
||||
def evaluate_pokemon_worth(pkmn, compare_level: nil)
|
||||
species_data = pkmn.species_data
|
||||
return 0 unless species_data
|
||||
|
||||
level = pkmn.level
|
||||
level_diff = compare_level ? (level - compare_level) : 0
|
||||
level_score = level * 2 + [level_diff, 0].max * 1.5 # bonus if player's level is higher
|
||||
|
||||
base_stats_score = species_data.base_stats.values.sum / 10.0
|
||||
rarity_score = (255 - species_data.catch_rate) / 5.0
|
||||
iv_score = (pkmn.iv&.values&.sum || 0) / 4.0
|
||||
shiny_score = pkmn.shiny? ? 50 : 0
|
||||
fusion_bonus = pkmn.isFusion? ? 40 : 0
|
||||
|
||||
score = level_score +
|
||||
base_stats_score +
|
||||
rarity_score +
|
||||
iv_score +
|
||||
shiny_score +
|
||||
fusion_bonus
|
||||
|
||||
echoln("#{pkmn.name} - Score : #{score}")
|
||||
return score
|
||||
end
|
||||
|
||||
|
||||
|
||||
def offerPokemonForTrade(player_pokemon, npc_party, trainer_class)
|
||||
player_score = evaluate_pokemon_worth(player_pokemon)
|
||||
pickiness = TRAINER_CLASS_PICKINESS[trainer_class] || 1.0
|
||||
|
||||
# Evaluate all NPC Pokémon scores
|
||||
npc_scores = npc_party.map do |npc_pkmn|
|
||||
[npc_pkmn, evaluate_pokemon_worth(npc_pkmn, compare_level: player_pokemon.level)]
|
||||
end
|
||||
best_npc_pokemon, best_score = npc_scores.max_by { |_, score| score }
|
||||
return best_npc_pokemon if player_score > best_score
|
||||
|
||||
max_difference = [player_score, 100].min * pickiness
|
||||
candidates = npc_scores.select do |npc_pkmn, npc_score|
|
||||
(npc_score - player_score).abs <= max_difference
|
||||
end
|
||||
|
||||
return nil if candidates.empty?
|
||||
candidates.min_by do |_, npc_score|
|
||||
(npc_score - player_score).abs
|
||||
end.first
|
||||
end
|
||||
|
||||
def doNPCTrainerTrade(trainer)
|
||||
echoln trainer.getTimeSinceLastTrade
|
||||
if trainer.isNextTradeReady?
|
||||
pbMessage(_INTL("The trainer is not ready to trade yet. Wait a little bit before you make your offer."))
|
||||
return trainer
|
||||
end
|
||||
return generateTrainerTradeOffer(trainer)
|
||||
end
|
||||
|
||||
#prefered type depends on the trainer class
|
||||
#
|
||||
def generateTrainerTradeOffer(trainer)
|
||||
bg_image_id=20
|
||||
wanted_type = trainer.favorite_type
|
||||
wanted_type = :NORMAL if !wanted_type
|
||||
|
||||
wanted_type_name = GameData::Type.get(wanted_type).real_name
|
||||
trainerClassName = GameData::TrainerType.get(trainer.trainerType).real_name
|
||||
pbMessage(_INTL("#{trainerClassName} #{trainer.trainerName} is looking for \\C[1]#{wanted_type_name}-type Pokémon\\C[0]. Which Pokémon do you want to trade?."),)
|
||||
pbChoosePokemon(1,2,
|
||||
proc {|pokemon|
|
||||
pokemon.hasType?(wanted_type)
|
||||
})
|
||||
|
||||
chosen_index = pbGet(1)
|
||||
echoln pbGet(1)
|
||||
if chosen_index && chosen_index >= 0
|
||||
chosen_pokemon = $Trainer.party[chosen_index]
|
||||
offered_pokemon = offerPokemonForTrade(chosen_pokemon,trainer.currentTeam,trainer.trainerType)
|
||||
if !offered_pokemon
|
||||
pbMessage(_INTL("#{trainerClassName} #{trainer.trainerName} does not want to trade..."))
|
||||
return trainer
|
||||
end
|
||||
|
||||
pif_sprite = BattleSpriteLoader.new.get_pif_sprite_from_species(offered_pokemon.species)
|
||||
pif_sprite.dump_info()
|
||||
|
||||
message = _INTL("#{trainerClassName} #{trainer.trainerName} is offering #{offered_pokemon.name} (Level #{offered_pokemon.level}) for your #{chosen_pokemon.name}.")
|
||||
showPokemonInPokeballWithMessage(pif_sprite, message)
|
||||
|
||||
if pbConfirmMessage(_INTL("Trade away #{chosen_pokemon.name} for #{trainerClassName} #{trainer.trainerName}'s #{offered_pokemon.name}?"))
|
||||
pbStartTrade(chosen_index, offered_pokemon,offered_pokemon.name,trainer.trainerName,0)
|
||||
updated_party = trainer.currentTeam
|
||||
updated_party.delete(offered_pokemon)
|
||||
updated_party << chosen_pokemon.clone
|
||||
trainer.previous_trade_timestamp= Time.now
|
||||
trainer.increase_friendship(20)
|
||||
return trainer
|
||||
end
|
||||
end
|
||||
return trainer
|
||||
|
||||
#todo
|
||||
#
|
||||
# NPC says "I'm looking for X or Y tyflpe Pokemon (prefered Pokemon can be determined when initializing from a pool of types that depends on the trainer class)
|
||||
# Also possible to pass a list of specific Pokemon in trainers.txt that the trainer will ask for instead if it's defined
|
||||
#
|
||||
# you select one of your Pokemon and he gives you one for it
|
||||
# prioritize recently caught pokemon
|
||||
# prioritive weaker Pokemon
|
||||
#
|
||||
#Assign a score to each Pokemon in trainer's team. calculate the same score for trainer's pokemon - select which
|
||||
# one is closer
|
||||
#
|
||||
# NPC says "I can offer A in exchange for your B.
|
||||
# -Yes -> Trade, update trainer team to put the player's pokemon in there
|
||||
# Cannot trade again with the same trainer for 5 minutes
|
||||
# "You just traded with this trainer. Wait a bit before you make another offer
|
||||
# -No
|
||||
trainer.set_pending_action(false) if trainer
|
||||
return trainer
|
||||
end
|
||||
Reference in New Issue
Block a user