• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

JSON to Essentials team importer/exporter + CPU trainers

4
Posts
5
Years
    • Seen Apr 28, 2022
    Introduction:
    Built from Cilerba and Marin's Essentials to Showdown exporter (https://www.pokecommunity.com/showthread.php?t=396771), I have scripts that can export your Pokémon in party to a Showdown-friendly JSON file, give you new Pokémon from such files, and let you start your own AI battles without adding anything to PBS/trainers.txt, by giving your opponent its team using those JSON files.

    Requirements:
    - Essentials v19.1 or higher
    - Ruby's standard library in your game's root directory, which comes with my battle simulator (https://www.pokecommunity.com/showthread.php?p=10402408#post10402408)

    How to use:
    - First, make a folder in the plugins folder of your game, and add meta.txt:
    Name = Essentials team importer/exporter + CPU opponents
    Version = 19.1.0
    Credits = AceOfSpadesProduc100, Cilerba and Marin (original Showdown exporter for Essentials), with the help of Vendily, and Nuri Yuri
    - After pasting the three scripts to that folder, make an event (like maybe an NPC) that prompts you to import or export a team. To import a team, call `importteam` which prompts you to enter a name (case-insensitive; no file extensions, meaning type in "demoteam" instead of "demoteam.json"). To export a team, call `pbShowdown`. All teams are in the saved teams folder.
    JSON to Essentials team importer/exporter + CPU trainers

    - To start a battle with your CPU opponent, add an event that calls `pbCPUTrainerBattle`, which prompts you to pick a battle theme, and then to load a team from a said JSON file by entering the name of the team.
    JSON to Essentials team importer/exporter + CPU trainers

    - If you want to come up with a new team, then you can either use Showdown's teambuilder and then run it through something like https://itsjavi.com/koffing/, or you can write your own team while following showdowntoessentialsguide.txt (https://1drv.ms/t/s!AkhwFcLqArMWgaaoYkGVyrUYAfKHOMs?e=oyhV2w) which comes with my battle simulator.

    Here's a demo team (demoteam.json):
    Code:
    {"teams":[{"pokemon":[{"name":"pikachu","level":50,"item":"Amulet Coin","ball":"POKEBALL","moves":["Slam","Thunderbolt","Agility","Wild Charge"],"form":0,"ability":"Static","ability_index":1,"nature":"MODEST","ivs":{"HP":6,"Atk":12,"Def":26,"SpA":12,"SpD":14,"Spe":1},"evs":{"HP":0,"Atk":0,"Def":0,"SpA":0,"SpD":0,"Spe":0},"happiness":73,"nickname":"Demoname","language":2,"timeReceived":1628899790,"shiny":false,"gender":"F"},{"name":"pidgeotto","level":50,"ball":"POKEBALL","moves":["Wing Attack","Roost","Tailwind","Fly"],"form":0,"ability":"Tangled Feet","ability_index":1,"nature":"CAREFUL","ivs":{"HP":2,"Atk":9,"Def":1,"SpA":10,"SpD":10,"Spe":16},"evs":{"HP":0,"Atk":0,"Def":0,"SpA":0,"SpD":0,"Spe":0},"happiness":73,"nickname":"Pidgeotto","language":2,"timeReceived":1628899790,"shiny":false,"gender":"F"},{"name":"kadabra","level":50,"ball":"POKEBALL","moves":["Role Play","Future Sight","Trick","Flash"],"form":0,"ability":"Synchronize","ability_index":1,"nature":"SERIOUS","ivs":{"HP":12,"Atk":8,"Def":4,"SpA":21,"SpD":13,"Spe":10},"evs":{"HP":0,"Atk":0,"Def":0,"SpA":0,"SpD":0,"Spe":0},"happiness":73,"nickname":"Kadabra","language":2,"timeReceived":1628899790,"shiny":false,"gender":"M"},{"name":"gyarados","level":50,"ball":"POKEBALL","moves":["Hurricane","Surf","Dive","Waterfall"],"form":0,"ability":"Intimidate","ability_index":1,"nature":"QUIET","ivs":{"HP":27,"Atk":27,"Def":25,"SpA":28,"SpD":4,"Spe":1},"evs":{"HP":0,"Atk":0,"Def":0,"SpA":0,"SpD":0,"Spe":0},"happiness":70,"nickname":"Gyarados","language":2,"timeReceived":1628899790,"shiny":false,"gender":"M"},{"name":"diglett","level":50,"ball":"POKEBALL","moves":["Dig","Cut","Headbutt","Rock Smash"],"form":0,"ability":"Sand Veil","ability_index":0,"nature":"QUIRKY","ivs":{"HP":13,"Atk":29,"Def":23,"SpA":27,"SpD":11,"Spe":2},"evs":{"HP":0,"Atk":0,"Def":0,"SpA":0,"SpD":0,"Spe":0},"happiness":73,"nickname":"Diglett","language":2,"timeReceived":1628899790,"shiny":false,"gender":"M"},{"name":"chansey","level":50,"ball":"POKEBALL","moves":["Egg Bomb","Light Screen","Strength","Sweet Scent"],"form":0,"ability":"Natural Cure","ability_index":0,"nature":"BASHFUL","ivs":{"HP":21,"Atk":2,"Def":16,"SpA":7,"SpD":6,"Spe":2},"evs":{"HP":0,"Atk":0,"Def":0,"SpA":0,"SpD":0,"Spe":0},"happiness":143,"nickname":"Chansey","language":2,"timeReceived":1628899790,"shiny":false,"gender":"F"}]}]}

    The team importer script:
    Code:
    #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=
    #
    #  Showdown JSON Importer for Pokémon Essentials by AceOfSpadesProduc100
    #
    #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=
    # Get the JSON library from the folder of the below name
    $:.push File.join(Dir.pwd, "Ruby Library 3.0.0")
    # Import the library
    require 'json'
    def importteam
    	filename = @scene.pbEnterText(_INTL("Name? (Case insensitive)"),1,12)
    	begin
    		file = File.read("Saved teams/" + filename + ".json")
    		data_hash = JSON.parse(file)
    		data_hash['teams'][0]['pokemon'].each do |i|
    			#.upcase.gsub(/\W/,'').to_sym means to convert into uppercase, include only letters and no spaces, and convert into a Ruby symbol, a variable with a : at the beginning
    			p = Pokemon.new(i['name'].upcase.gsub(/\W/,'').to_sym,i['level'] ? i['level'] : 50)
    			plevel = i['level'] ? i['level'] : 50
    			p.item = i['item'].upcase.gsub(/\W/,'').to_sym if i['item']
    			p.poke_ball = i['ball'].upcase.gsub(/\W/,'').to_sym if i['ball']
    			if i['moves'] && i['moves'].length > 0
    				i['moves'].each do |j|
    					p.learn_move(j.upcase.gsub(/\W/,'').to_sym)
    				end
    			else
    				p.reset_moves
    			end
    			p.form = i['form'] if i['form']
    			if i['gender'] == 'M'
    				p.makeMale
    			else
    				p.makeFemale
    			end
    			p.ability= i['ability'] if i['ability']
    			p.ability_index = i['ability_index'] if i['ability_index']
    			p.shiny = i['shiny'] if i['shiny']
    			p.nature = i['nature'].upcase.gsub(/\W/,'').to_sym if i['nature']
    			if i['ivs']
    				p.iv[:HP] = i['ivs']['HP'] ? i['ivs']['HP'] : p.iv[:HP] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:ATTACK] = i['ivs']['Atk'] ? i['ivs']['Atk'] : p.iv[:ATTACK] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:DEFENSE] = i['ivs']['Def'] ? i['ivs']['Def'] : p.iv[:DEFENSE] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:SPECIAL_ATTACK] = i['ivs']['SpA'] ? i['ivs']['SpA'] : p.iv[:SPECIAL_ATTACK] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:SPECIAL_DEFENSE] = i['ivs']['SpD'] ? i['ivs']['SpD'] : p.iv[:SPECIAL_DEFENSE] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:SPEED] = i['ivs']['Spe'] ? i['ivs']['Spe'] : p.iv[:SPEED] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    			else
    				p.iv[:HP] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:ATTACK] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:DEFENSE] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:SPECIAL_ATTACK] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:SPECIAL_DEFENSE] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    				p.iv[:SPEED] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
    			end
    			if i['evs']
    				p.ev[:HP] = i['evs']['HP'] ? i['evs']['HP'] : p.ev[:HP] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:ATTACK] = i['evs']['Atk'] ? i['evs']['Atk'] : p.ev[:ATTACK] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:DEFENSE] = i['evs']['Def'] ? i['evs']['Def'] : p.ev[:DEFENSE] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:SPECIAL_ATTACK] = i['evs']['SpA'] ? i['evs']['SpA'] : p.ev[:SPECIAL_ATTACK] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:SPECIAL_DEFENSE] = i['evs']['SpD'] ? i['evs']['SpD'] : p.ev[:SPECIAL_DEFENSE] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:SPEED] = i['evs']['Spe'] ? i['evs']['Spe'] : p.ev[:SPEED] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    			else
    				p.ev[:HP] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:ATTACK] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:DEFENSE] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:SPECIAL_ATTACK] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:SPECIAL_DEFENSE] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    				p.ev[:SPEED] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
    			end
    			p.happiness = i['happiness'] if i['happiness']
    			p.name = i['nickname'] if i['nickname']
    			p.owner.language = i['language'] if i['language']
    			p.timeReceived = Time.at(i['timeReceived']) if i['timeReceived']
    			p.calc_stats
    			(0) rescue nil; pbAddPokemonSilent(p)
    		end
    		pbMessage(_INTL($Trainer.name + "\\se[] obtained some Pokémon!\\me[Pkmn get]\\wtnp[30]"))
    	rescue
    		pbMessage(_INTL("An error occurred. Check for JSON-specific errors in a JSON validator, or refer to \"showdowntoessentialsguide.txt\" for team-specific errors.")) 
    	end
    end

    The team exporter script:
    Code:
    #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
    #
    #  Essentials Exporter by AceOfSpadesProduc100, built from Showdown Exporter v2 for Pokémon Essentials by Cilerba and Marin, rewritten by Nuri Yuri
    #
    #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
    $:.push File.join(Dir.pwd, "Ruby Library 3.0.0")
    require 'json'
    
    ESSENTIALS_IV_TO_SHOWDOWN = { HP: 'HP', ATTACK: 'Atk', DEFENSE: 'Def', SPECIAL_ATTACK: 'SpA', SPECIAL_DEFENSE: 'SpD', SPEED: 'Spe' }
    
    def pbShowdown
      party = $Trainer.party.compact.map do |pokemon|
        next {
          name: pokemon.species.name.to_s.downcase,
          level: pokemon.level,
          item: pokemon.hasItem? ? pokemon.item.name : nil,
          ball: pokemon.poke_ball,
          moves: pokemon.moves.compact.reject { |move| move.id == 0 }.map { |move| move.name.to_s },
          form: pokemon.form,
          ability: pokemon.ability.name,
          ability_index: pokemon.ability_index,
          nature: pokemon.nature.id,
          ivs: pokemon.iv.select { |_, v| v < 31 }.transform_keys { |k| ESSENTIALS_IV_TO_SHOWDOWN[k] },
          evs: pokemon.ev.select { |_, v| v >= 0 }.transform_keys { |k| ESSENTIALS_IV_TO_SHOWDOWN[k] },
          happiness: pokemon.happiness,
          nickname: pokemon.name.to_s,
          language: pokemon.owner.language,
          timeReceived: pokemon.timeReceived.to_i,
          shiny: pokemon.shiny?,
          gender: pokemon.gender == 0 ? 'M' : 'F'
        }.compact
      end
      filename = @scene.pbEnterText(_INTL("Name for the team?"), 1, 12)
      Dir.mkdir("Saved teams/") if !Dir.exists?("Saved teams/")
    	file = File.new("Saved teams/" + filename + ".json", "w+")
    	file.write({ teams: [{ pokemon: party }] }.to_json)
    end

    The CPU trainers script:
    Code:
    #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
    #
    #  Showdown JSON Importer for Pokémon Essentials CPU Opponents by AceOfSpadesProduc100, built from Trainer.to_trainer from Pokémon Essentials v19.1
    #
    #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
    $:.push File.join(Dir.pwd, "Ruby Library 3.0.0")
    require 'json'
    def importopponent
    	filename = @scene.pbEnterText(_INTL("Name for the opponent team?"),1,12)
    	begin
            file = File.read("Saved teams/" + filename + ".json")
    		data_hash = JSON.parse(file)
            # Create trainer object
            tr_name = "CPU Player"
            trainer = NPCTrainer.new(tr_name, :CPUPLAYER)
            trainer.id        = $Trainer.make_foreign_ID
            trainer.items     = nil
            trainer.lose_text = ""
            data_hash['teams'][0]['pokemon'].each do |pkmn_data|
                species = GameData::Species.get(pkmn_data['name'].upcase.gsub(/\W/,'')).species
                pkmn = Pokemon.new(species, pkmn_data['level'] ? pkmn_data['level'] : 50, trainer, false)
                plevel = pkmn_data['level'] ? pkmn_data['level'] : 50
                trainer.party.push(pkmn)
                # Set Pokémon's properties if defined
                if pkmn_data['form']
                    pkmn.forced_form = pkmn_data['form'] if MultipleForms.hasFunction?(species, "getForm")
                    pkmn.form_simple = pkmn_data['form']
                end
                pkmn.item = pkmn_data['item'].upcase.gsub(/\W/,'').to_sym if pkmn_data['item']
                if pkmn_data['moves'] && pkmn_data['moves'].length > 0
                    pkmn_data['moves'].each { |move| pkmn.learn_move(move.upcase.gsub(/\W/,'').to_sym) }
                else
                    pkmn.reset_moves
                end
                pkmn.ability_index = pkmn_data['ability_index'] if pkmn_data['ability_index']
                pkmn.ability = pkmn_data['ability'] if pkmn_data['ability']
                if pkmn_data['gender'] == "M"
                    pkmn.gender = 0
                else
                    pkmn.gender = 1
                end
                pkmn.shiny = (pkmn_data['shiny']) ? true : false
                if pkmn_data['nature']
                    pkmn.nature = pkmn_data['nature']
                else
                    nature = pkmn.species_data.id_number + GameData::TrainerType.get(trainer.trainer_type).id_number
                    pkmn.nature = nature % (GameData::Nature::DATA.length / 2)
                end
                    if pkmn_data['ivs']
                        pkmn.iv[:HP] = pkmn_data['ivs']['HP'] ? pkmn_data['ivs']['HP'] : pkmn.iv[:HP] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:ATTACK] = pkmn_data['ivs']['Atk'] ? pkmn_data['ivs']['Atk'] : pkmn.iv[:ATTACK] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:DEFENSE] = pkmn_data['ivs']['Def'] ? pkmn_data['ivs']['Def'] : pkmn.iv[:DEFENSE] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:SPECIAL_ATTACK] = pkmn_data['ivs']['SpA'] ? pkmn_data['ivs']['SpA'] : pkmn.iv[:SPECIAL_ATTACK] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:SPECIAL_DEFENSE] = pkmn_data['ivs']['SpD'] ? pkmn_data['ivs']['SpD'] : pkmn.iv[:SPECIAL_DEFENSE] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:SPEED] = pkmn_data['ivs']['Spe'] ? pkmn_data['ivs']['Spe'] : pkmn.iv[:SPEED] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                    else
                        pkmn.iv[:HP] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:ATTACK] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:DEFENSE] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:SPECIAL_ATTACK] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:SPECIAL_DEFENSE] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                        pkmn.iv[:SPEED] = [plevel / 2, Pokemon::IV_STAT_LIMIT].min
                    end
                    if pkmn_data['evs']
                        pkmn.ev[:HP] = pkmn_data['evs']['HP'] ? pkmn_data['evs']['HP'] : pkmn.ev[:HP] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:ATTACK] = pkmn_data['evs']['Atk'] ? pkmn_data['evs']['Atk'] : pkmn.ev[:ATTACK] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:DEFENSE] = pkmn_data['evs']['Def'] ? pkmn_data['evs']['Def'] : pkmn.ev[:DEFENSE] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:SPECIAL_ATTACK] = pkmn_data['evs']['SpA'] ? pkmn_data['evs']['SpA'] : pkmn.ev[:SPECIAL_ATTACK] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:SPECIAL_DEFENSE] = pkmn_data['evs']['SpD'] ? pkmn_data['evs']['SpD'] : pkmn.ev[:SPECIAL_DEFENSE] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:SPEED] = pkmn_data['evs']['Spe'] ? pkmn_data['evs']['Spe'] : pkmn.ev[:SPEED] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                    else
                        pkmn.ev[:HP] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:ATTACK] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:DEFENSE] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:SPECIAL_ATTACK] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:SPECIAL_DEFENSE] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                        pkmn.ev[:SPEED] = [plevel * 3 / 2, Pokemon::EV_LIMIT / 6].min
                    end
                pkmn.happiness = pkmn_data['happiness'] if pkmn_data['happiness']
                pkmn.name = pkmn_data['nickname'] if pkmn_data['nickname'] && !pkmn_data['nickname'].empty?
                pkmn.poke_ball = pkmn_data['ball'] if pkmn_data['ball']
                pkmn.calc_stats
            end
            return trainer
        rescue
    		pbMessage(_INTL("An error occurred. Check for JSON-specific errors in a JSON validator, or refer to \"showdowntoessentialsguide.txt\" for team-specific errors."))
    	end
    end
    def pbCPUTrainerBattle(doubleBattle=false, canLose=false, outcomeVar=1)
        begin
            setBattleRule("outcomeVar",outcomeVar) if outcomeVar!=1
            setBattleRule("canLose") if canLose
            setBattleRule("double") if doubleBattle
            $PokemonGlobal.nextBattleBGM = pbListScreen("Battle theme", MusicFileLister.new(true,nil))
            ret = pbOrganizedBattleEx(importopponent,nil,
            "",
            "")
            return ret
        rescue
            pbMessage(_INTL("The battle didn't start, because of an error."))
        end
      end

    Credits: AceOfSpadesProduc100, Cilerba and Marin (original Showdown exporter for Essentials), with the help of Vendily, and Nuri Yuri
     
    Last edited:
    Back
    Top